zoj 3164 分组背包 + 各种背包
来源:互联网 发布:excel跨工作簿引用数据 编辑:程序博客网 时间:2024/05/17 06:00
把所有的背包结合起来的一道终极背包题,做了的话背包一般就没问题了
题意:给你n个种类的物品的描述,背包容量D
每个种类有三个属性 K E P
K表示这类物品最多可以选多少个,如果为0表示可以选无限多个
E表示选择这类物品每个物品的价值
P表示每个物品的花费
如果单纯是这样,那这道题目就太水了,直接多重背包就ok了
所以题目又加了点,而这一点想了我n久 啊
题目还将一些种类的物品分了个组,每组种类中最多只能选一个种类的物品
即加上了分组背包,按理说再往多重背包上套个分组背包不久好了,但是仔细想想发现每一组物品是由一些种类的物品组成的,只能在里面选一类,而每一类物品又有自己的性质,所以不好搞。
做法是这样的:
开个临时数组,用来记录那些被分组种类的物品的状态,w[i][j]表示第i组物品容量为j时的最大获利(相当于预处理)
其他没被分组的物品直接进行多重背包就行了
具体见代码吧(如果对各种背包不是很了解的可以先看看背包九讲)
View Code
#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;const int maxn = 1500;const int inf = ~0u>>2;struct node{ int K,E,P;}in[maxn];int dp[maxn];int n,m;char s[100000];int flag[maxn];void init(int dp[]){ fill(dp,dp+m+1,-inf); dp[0]=0;}void complete(int w,int val,int dp[]){ for(int i=w;i<=m;i++)if(dp[i-w]>-inf) dp[i]=max(dp[i-w]+val,dp[i]);}void zero_one(int w,int val,int dp[]){ for(int j=m;j>=w;j--)if(dp[j-w]>-inf) dp[j]=max(dp[j-w]+val,dp[j]);}int w[10][maxn];int tmp[maxn];int main(){ while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++)scanf("%d%d%d",&in[i].K,&in[i].E,&in[i].P); int G; scanf("%d",&G);getchar(); vector<int> group[10]; memset(flag,0,sizeof(flag)); for(int i=1;i<=G;i++){ gets(s); int len=strlen(s); for(int j=0;j<len;){ if(s[j]>='1'&&s[j]<='9'){ int sum=0; while(s[j]>='0' && s[j] <= '9'){ sum=sum*10+s[j]-'0'; j++; } flag[sum]=i; } else j++; } } init(dp); for(int i=1;i<=G;i++) init(w[i]); for(int i=1;i<=n;i++){ if(flag[i]) init(tmp); if(in[i].K==0 || in[i].K*in[i].P>=m) complete(in[i].P,in[i].E,flag[i] ? tmp : dp); else { int k=1,count=in[i].K; while(k<count){ zero_one(k*in[i].P,in[i].E*k,flag[i] ? tmp : dp); count-=k; k<<=1; } zero_one(count*in[i].P,count*in[i].E,flag[i] ? tmp : dp); } if(flag[i]) for(int j=0;j<=m;j++) w[flag[i]][j]=max(w[flag[i]][j],tmp[j]); } for(int i=1;i<=G;i++) for(int v=m;v>=0;v--) for(int j=0;j<=v;j++) if(dp[v-j] > -inf && w[i][j] > -inf) dp[v]=max(dp[v],dp[v-j]+w[i][j]); if(dp[m]>=0) printf("%d\n",dp[m]); else printf("i'm sorry...\n"); } return 0;}
- zoj 3164 分组背包 + 各种背包
- zoj 3164 各种背包
- ZOJ 3769 (分组背包)
- zoj 3164 Cookie Choice (分组混合背包)
- Zoj 3164 Cookie Choice(多重背包+分组背包,更新队列优化)
- zoj 3769 Diablo III (分组背包+优化+背包细节)
- hdu 3535 AreYouBusy(各种分组背包)
- hdu 3535 AreYouBusy[各种分组背包]
- 背包·分组背包
- 分组背包
- 分组 背包
- 分组背包
- 分组背包
- 分组背包
- 分组背包
- 分组背包
- 分组背包
- 分组背包
- poj 2831 次小生成树
- hdu 1421 经典DP
- zoj 3527 带环的树形DP
- zoj 3475 最小割 巧妙建图
- spfa算法的优化及应用 poj 2949
- zoj 3164 分组背包 + 各种背包
- codeforces 154 A DP
- python dictionary
- android用异步操作AsyncTask编写文件查看器
- 我国第三方支付交易市场发展现状调查解析
- python list
- 网络性能优化(NAPI)
- Codeforces Round #137 (Div. 2) / 222A Shooshuns and Sequence (模拟)
- 多校第四场