AtCoder Beginner Contest 145 E - All-you-can-eat ###K ###K //K

题目链接:https://atcoder.jp/contests/abc145/tasks/abc145_e

题意:有n道菜,每道菜需要a[i]分吃完,能获得b[i]的美味值 给T分钟,问怎么样吃,才能在T内得到最多的美味值,

一旦开始了吃就一定会吃完这道菜,哪怕时间超过T分

思路:很明显的01背包问题,不过是多了一个 某一道菜不受时间限制 的条件 很容易看出这里的一个 贪心就是 用1分钟给一道菜 这样是最优解

那么 此时的T就变为T-1 然后考虑01背包dp

加一维的空间满足 他有没有用上这 1分钟的条件 ,1为有 0为没有

关键的转移是 在x等于1的时候也要 用上   

if(j>=w[i])
{
  dp[i][j][x]=max(dp[i][j][x],dp[i-1][j-w[i]][x]+v[i]);
}         当已经使用了这个条件后, 此时就和0 的时候是等价的 ,剩下的也是转换为取和不取的问题, 否则 的话 1的状态无法延续下去

二维01背包的代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =1e6+10;
 6 const int mod=998244353;
 7 int w[3010];
 8 int v[3010];
 9 int dp[3010][3010][2];
10 
11 
12 
13 int main()
14 {
15     ios::sync_with_stdio(false);
16     cin.tie(0);
17     int n,t;
18     cin>>n>>t;
19     t--;
20     for(int i=1;i<=n;i++)
21         cin>>w[i]>>v[i];
22     //int ans=0;
23     for(int i=1;i<=n;i++)
24     {
25        for(int j=0;j<=t;j++)
26        {
27            dp[i][j][0]=dp[i-1][j][0];
28            dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j][0]+v[i]);
29            if(j>=w[i])
30            {
31                dp[i][j][0]=max(dp[i][j][0],dp[i-1][j-w[i]][0]+v[i]);
32                dp[i][j][1]=max(dp[i][j][1],dp[i-1][j-w[i]][1]+v[i]);
33            }
34            //ans=max({ans,dp[i][j][0],dp[i][j][1]});
35        }
36     }
37     cout<<dp[n][t][1]<<'\n';
38 
39 
40 
41 
42 }
View Code

 

 

也可以优化成一维01背包的代码 

要注意的是 先 更新1 在更新0  不然会重复拿同一样东西 因为1的时候要通过0来更新 当然逆序是肯定的

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =1e6+10;
 6 const int mod=998244353;
 7 int w[3010];
 8 int v[3010];
 9 int dp[3010][2];
10 
11 
12 
13 int main()
14 {
15     ios::sync_with_stdio(false);
16     cin.tie(0);
17     int n,t;
18     cin>>n>>t;
19     t--;
20     for(int i=1;i<=n;i++)
21         cin>>w[i]>>v[i];
22     for(int i=1;i<=n;i++)
23     {
24         for(int j=t;j>=0;j--)
25         {
26             dp[j][1]=max(dp[j][1],dp[j][0]+v[i]);
27             if(j>=w[i])
28             {
29                 dp[j][1]=max(dp[j][1],dp[j-w[i]][1]+v[i]);
30                 dp[j][0]=max(dp[j][0],dp[j-w[i]][0]+v[i]);
31             }
32         }
33     }
34     cout<<dp[t][1]<<'\n';
35 
36 
37 
38 
39 }
View Code

 

posted @ 2020-07-11 17:15  canwinfor  阅读(294)  评论(0)    收藏  举报