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 }

 




posted @ 2017-02-23 17:42  _yxg123  阅读(85)  评论(0编辑  收藏  举报