bzoj4247 挂饰 背包DP
思路:
背包问题,dp[i][j]表示在考虑第i个物品的时候,还剩下j个挂钩
注意,要按照挂钩多少排序,如果不排序的话,挂钩有可能会变成负数,然后又被加成正数
代码抄自:http://blog.csdn.net/creationaugust/article/details/48133509
这个初始化 和 这个转换: 把一开始读入体积为0的物品的体积当成1,不为0的当成-v+1来做背包.
想不到啊
dp[i][j] = max(dp[i-1][j],dp[i-1][j-a[i].x+1]+a[i].y); // dp[i][n+1]=-INF 是 j-a[i].x+1 当j=n, a[i].x=0 时
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define mem(a) memset(a,0,sizeof(a)) 5 #define mp(x,y) make_pair(x,y) 6 const int INF = 0x3f3f3f3f; 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 8 inline ll read(){ 9 ll x=0,f=1;char ch=getchar(); 10 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 11 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 12 return x*f; 13 } 14 ////////////////////////////////////////////////////////////////////////// 15 const int maxn = 2e3+10; 16 17 ll dp[maxn][maxn]; 18 19 struct node{ 20 int x,y; 21 }a[maxn]; 22 23 bool cmp(node A,node B){ 24 return A.x > B.x; 25 } 26 27 int main(){ 28 int n = read(); 29 for(int i=1; i<=n; i++) 30 a[i].x=read(),a[i].y=read(); 31 sort(a+1,a+1+n,cmp); 32 for(int i=0; i<=n; i++) 33 dp[0][i] = dp[i][n+1] = -INF; 34 dp[0][1] = 0; 35 36 for(int i=1; i<=n; i++) 37 for(int j=0; j<=n; j++){ 38 dp[i][j] = max(dp[i-1][j],dp[i-1][max(j-a[i].x,0)+1]+a[i].y); 39 // if(j<a[i].x) 40 // dp[i][j] = max(dp[i-1][j],dp[i-1][1]+a[i].y); 41 // else 42 // dp[i][j] = max(dp[i-1][j],dp[i-1][j-a[i].x+1]+a[i].y); 43 } 44 45 ll ans = -INF; 46 for(int i=0; i<=n; i++) 47 ans = max(ans,dp[n][i]); 48 cout << ans << endl; 49 50 return 0; 51 }