2015年CCPC D题 Pick The Sticks(DP)
2015-11-01 20:02
381 查看
0,10,1背包问题,赛后听了秦总队友的讲解会了。增加一维:
dp[k][i][v]dp[k][i][v]:
第一维:k=0,1,2k=0,1,2。00代表没有半截的情况,11代表有11个半截的情况,22代表有22个半截的情况。
第二维:前ii物品。
第三位:占了vv容量。
那么DPDP转移方程为:
dp[0][i][v]=max(dp[0][i−1][v],dp[0][i−1][v−c[i]]+w[i])dp[1][i][v]=max(dp[1][i−1][v],dp[1][i−1][v−c[i]]+w[i],dp[0][i−1][v−c[i]2]+w[i])dp[2][i][v]=max(dp[2][i−1][v],dp[2][i−1][v−c[i]]+w[i],dp[1][i−1][v−c[i]2]+w[i])dp[0][i][v]=max(dp[0][i-1][v],dp[0][i-1][v-c[i]]+w[i])\\
dp[1][i][v]=max(dp[1][i-1][v],dp[1][i-1][v-c[i]]+w[i],dp[0][i-1][v-{c[i]\over{2}}]+w[i])\\
dp[2][i][v]=max(dp[2][i-1][v],dp[2][i-1][v-c[i]]+w[i],dp[1][i-1][v-{c[i]\over{2}}]+w[i])
小tricktrick:
11:对于容量c[i]2{c[i]\over{2}}不能被22整除时,要把它变成整数,所以初始化的时候c[i]<<=1c[i]<<=1。
22:只放11个物品的时候,无论背包容量有多大,任何物品都能放进去。
代码:
dp[k][i][v]dp[k][i][v]:
第一维:k=0,1,2k=0,1,2。00代表没有半截的情况,11代表有11个半截的情况,22代表有22个半截的情况。
第二维:前ii物品。
第三位:占了vv容量。
那么DPDP转移方程为:
dp[0][i][v]=max(dp[0][i−1][v],dp[0][i−1][v−c[i]]+w[i])dp[1][i][v]=max(dp[1][i−1][v],dp[1][i−1][v−c[i]]+w[i],dp[0][i−1][v−c[i]2]+w[i])dp[2][i][v]=max(dp[2][i−1][v],dp[2][i−1][v−c[i]]+w[i],dp[1][i−1][v−c[i]2]+w[i])dp[0][i][v]=max(dp[0][i-1][v],dp[0][i-1][v-c[i]]+w[i])\\
dp[1][i][v]=max(dp[1][i-1][v],dp[1][i-1][v-c[i]]+w[i],dp[0][i-1][v-{c[i]\over{2}}]+w[i])\\
dp[2][i][v]=max(dp[2][i-1][v],dp[2][i-1][v-c[i]]+w[i],dp[1][i-1][v-{c[i]\over{2}}]+w[i])
小tricktrick:
11:对于容量c[i]2{c[i]\over{2}}不能被22整除时,要把它变成整数,所以初始化的时候c[i]<<=1c[i]<<=1。
22:只放11个物品的时候,无论背包容量有多大,任何物品都能放进去。
代码:
#include <bits/stdc++.h> #define LL long long #define FOR(i,x,y) for(int i = x;i < y;++ i) #define IFOR(i,x,y) for(int i = x;i > y;-- i) using namespace std; const int Mod = 1000000007; const int maxN = 1010; const int maxL = 4040; LL dp[3][maxL]; int n,l,c[maxN],w[maxN]; void init(){ scanf("%d%d",&n,&l); l <<= 1; FOR(i,1,n+1){ scanf("%d%d",&c[i],&w[i]); c[i] <<= 1; } memset(dp,0,sizeof(dp)); } LL DP0(int i,int v){ LL res = dp[0][v]; if(v >= c[i]) res = max(res,dp[0][v-c[i]]+w[i]); return res; } LL DP1(int i,int v){ LL res = dp[1][v]; if(v >= (c[i]+1)/2){ res = max(res,dp[0][v-c[i]/2]+w[i]); if(v >= c[i]){ res = max(res,dp[1][v-c[i]]+w[i]); } } return res; } LL DP2(int i,int v){ LL res = dp[2][v]; if(v >= (c[i]+1)/2){ res = max(res,dp[1][v-c[i]/2]+w[i]); if(v >= c[i]){ res = max(res,dp[2][v-c[i]]+w[i]); } } return res; } void work(){ FOR(i,1,n+1){ IFOR(v,l,0){ dp[0][v] = DP0(i,v); dp[1][v] = DP1(i,v); dp[2][v] = DP2(i,v); } } LL t = -1; FOR(i,1,n+1) t = max(t,(LL)w[i]); printf("%lld\n",max(dp[2][l],t)); } int main(){ //freopen("test.in","r",stdin); int T,tCase = 0; scanf("%d",&T); while(T--){ printf("Case #%d: ",++tCase); init(); work(); } return 0; }
相关文章推荐
- Git
- jspsmartupload上传文件名中文乱码和超链接传递路径参数encodeURIComponent加解码
- ACM学习历程—HDU1023 Train Problem II(递推 && 大数)
- 向SQL2008R2导入Acess、excel数据
- LeetCode----Word Pattern
- 【设计模式】——面向对象基础
- 2-50之间的素数列表
- 威佐夫博弈(介绍)
- 图的最小生成树Kruskal算法
- 基于DFA的C程序注释删除
- Java____Synchronized++之前线程进程学习链接
- 信息安全系统设计基础期中总结
- spring与web整合(交鸡肋,因为有前台框架封装了servlet)
- 哈夫曼树知识点
- Java环境变量配置
- BC#62C题求二叉树不同节点数的子树的个数
- Unity重力的测试
- 永久性保存
- JS学习实例:JavaScript时钟及Date对象学习总结
- 大整数取模