bzoj4247: 挂饰(背包)
4247: 挂饰
题目:传送门
题解:
看完题目很明显的一道二维背包(一开始还推错了)
设f[i][j]表示前i个挂饰选完(可以有不选)之后还剩下j个挂钩的最大值(j最多贡献为n)
那么f[i][j]=max(f[i-1][j],f[i-1][max(j-a[i].w,0)+1]+a[i].x);(一开始忘了加1真的是沙茶)
然后就直接乱打一通...然后又错了
再想想,如果前面的好几个物品都没有挂钩...那我怎么转移,所以排序一下挂钩数目咯
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 struct node 8 { 9 int w,x; 10 }a[2100]; 11 int n,f[2100][2100];//前i个物品剩j个挂钩 12 bool cmp(node n1,node n2){return n1.w>n2.w;} 13 int main() 14 { 15 scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d",&a[i].w,&a[i].x); 16 sort(a+1,a+n+1,cmp); 17 for(int i=0;i<=n;i++)for(int j=0;j<=n+1;j++)f[i][j]=-999999999;f[0][1]=0; 18 for(int i=1;i<=n;i++) 19 for(int j=0;j<=n;j++) 20 f[i][j]=max(f[i-1][j],f[i-1][max(j-a[i].w,0)+1]+a[i].x); 21 int ans=-999999999;for(int i=0;i<=n;i++)ans=max(ans,f[n][i]); 22 printf("%d\n",ans); 23 return 0; 24 }