博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu3033 I love sneakers! && hdu3535 AreYouBusy (组合背包)
阅读量:4584 次
发布时间:2019-06-09

本文共 2697 字,大约阅读时间需要 8 分钟。

hdu3033 题目要求与普通的组合背包(每组至多选一个)有所区别,而本题目的话,每组至少选一个,

那么如何保证每组至少选一个呢,问题就在初始化的问题还有状态转移的问题了

if(f[i][l-br[i].b[j]]!=-1 && f[i][l]<f[i][l-br[i].b[j]]+br[i].c[j]) //从当前组再多选一个

                        f[i][l]=f[i][l-br[i].b[j]]+br[i].c[j];

 if(f[i-1][l-br[i].b[j]]!=-1 && f[i][l]<f[i-1][l-br[i].b[j]]+br[i].c[j]) //在上一组的状态下,选当前组的一个

                        f[i][l]=f[i-1][l-br[i].b[j]]+br[i].c[j];

就上面这段关键的代码

 在某一状态存在的情况下(不等于-1),找出三种状态中最大的,赋值给f[i][j] .由于开始时所有f[i][j](i!=0)都为-1,所以更新时一定会从f[0][]开始,而此时就可保证当i=1时,f[i][j]中所有值不为-1的状态一定装了品牌1的某个物品。而当i>1时,

       要想得到 最初 的f[i][j],一定是从已经放有前i-1个品牌的某个状态得到的,而更新最初 的f[i][j] 也一定会用到i品牌的某
       个产品(都可由状态转移方程可知)。
       总之,保证每一类品牌 至少放一件产品是通过赋初值,条件判断,状态转移三方面实现的

 

#include
#include
#include
using namespace std;int n,m,k;__int64 f[11][10010];int num[11];struct brand{ int b[101],c[101];}br[11];int main(){ while(scanf("%d %d %d",&n,&m,&k)==3) { int a; memset(num,0,sizeof(num)); for(int i=0;i
=0;l--) { if(l

 

 hdu3535 理解了上面3033之后,这道题目其实也差不多,问题就出在赋初值的问题上了,对了每组至少选一个的情况我们已经知道了,但对于,任意选还有至多选一个的情况,初值当然是复制前一组的状态了,可是,如果不复制前一组的状态,后面的状态转移应该怎么处理,我怎么想也想不透

#include
#include
#define maxn 101#define inf 99999999using namespace std;struct object{ int c,g;};struct sett{ int k,s; object w[110]; }set[110];int T,n,m,dp[110][maxn];int main(){ while(scanf("%d %d",&n,&T)==2) { for(int i=1;i<=n;i++) for(int j=0;j<=T;j++) dp[i][j]=-inf; for(int i=1;i<=n;i++) { scanf("%d %d",&set[i].k,&set[i].s); for(int j=0;j
=set[i].w[j].c;t--) { int v=set[i].w[j].c,cost=set[i].w[j].g; int last=dp[i-1][t-v]+cost; int cur=dp[i][t-v]+cost; dp[i][t]=max(last,max(dp[i][t],cur)); } break; case 1: for(int j=0;j<=T;j++) dp[i][j]=dp[i-1][j]; for(int j=0;j
=set[i].w[j].c;t--) { int v=set[i].w[j].c,cost=set[i].w[j].g; int last=dp[i-1][t-v]+cost; // dp[i][t]=max(dp[i][t],max(dp[i-1][t],last)); dp[i][t]=max(dp[i][t],last);//要么不选,要么从上一组的状态,在当前组选一个 } break; case 2: for(int j=0;j<=T;j++) dp[i][j]=dp[i-1][j]; for(int j=0;j
=set[i].w[j].c;t--) { int v=set[i].w[j].c,cost=set[i].w[j].g; int cur=dp[i][t-v]+cost; int last=dp[i-1][t-v]+cost; // dp[i][t]=max(dp[i-1][t],max(dp[i][t],max(cur,last))); dp[i][t]=max(dp[i][t],max(last,cur));//比上一种情况多了一种选择, 就是可以从当前组继续多选择一个 } break; } } if(dp[n][T]<0) puts("-1"); else printf("%d\n",dp[n][T]); } return 0;}

 

 

 

 

转载于:https://www.cnblogs.com/nanke/archive/2011/11/24/2261695.html

你可能感兴趣的文章
多线程同步的几种方法
查看>>
数据结构-冒泡排序
查看>>
关于程序状态字寄存器PSW(Program Status Word)与多核多线程
查看>>
mybatis的缓存
查看>>
java 缓冲流 Buffer
查看>>
7月23号=》261页-265页
查看>>
软考知识点梳理--综合布线
查看>>
Mysql5.6主从热备配置
查看>>
VS2010DebugView捕捉
查看>>
mfix中更改time dependent VTK filename的最大时间步数的容量
查看>>
Windows7安装 docker-compose的过程
查看>>
关于nodeJS多线程的支持,目前看来无法实现,讲解v8的一些东西
查看>>
php递归创建文件夹的两种方法
查看>>
6.新增事件
查看>>
|洛谷|二分|P1182 数列分段Section II
查看>>
少儿编程Scratch第四讲:射击游戏的制作,克隆的奥秘
查看>>
Oracle学习第七课-表连接及其应用
查看>>
Python基础篇【第十三篇】:面向对象
查看>>
bzoj 2465 小球
查看>>
String类
查看>>