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
",ans);
23     return 0;
24 }
原文地址:https://www.cnblogs.com/CHerish_OI/p/8804530.html