线性dp总结2

转换成 状态机的 线性dp来写

状态机转移 只会从i-1来

 

题目一

题目链接:http://noi.openjudge.cn/ch0206/8462/

同样可以根据 当前有抢劫/无抢劫 画出状态机图

  抢 -> 没抢   没抢->没抢  没抢->抢  画出这个环形图即可  不要忘记边权

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

 

 

 

题目二

题目链接:https://www.acwing.com/problem/content/1059/

画出状态机转移图 对着写dp方程即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 const int mod=1e8;
 5 #define ll long long
 6 #define pb push_back
 7 int dp[maxn][110][2];// 前i天正在进行j次交易 是/否持有股票
 8 int a[maxn];
 9 
10 
11 int main()
12 {
13     ios::sync_with_stdio(0);
14     cin.tie(0);
15     int n,k;
16     cin>>n>>k;
17     for(int i=1;i<=n;i++)
18         cin>>a[i];
19     memset(dp,-0x3f,sizeof(dp));
20     dp[0][0][0]=0;
21     for(int i=1;i<=n;i++)
22     {
23         for(int j=0;j<=k;j++)
24         {
25             dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]+a[i]);
26             if(j)
27             dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j-1][0]-a[i]);
28         }
29     }
30     int ans=0;
31     for(int i=0;i<=k;i++)
32         ans=max(ans,dp[n][i][0]);
33     cout<<ans<<'\n';
34 
35 
36 
37 
38 
39 
40 }
View Code

dp[i][j][k] 代表第i天 交易了j次 当前是否持有股票     最后枚举0~k次取最大值即可  注意初始化

 

 

 

题目三

题目链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/

leetcode的题目  也是画出 有和无 以及冷冻期的三者关系  根据来写转移方程即可

 1 class Solution {
 2 public:
 3     int dp[100005][3];
 4     int maxProfit(vector<int>& prices) 
 5     {
 6         int ans=0;
 7         memset(dp,-0x3f,sizeof(dp));
 8         int n=prices.size();
 9         vector<int>w=prices;
10         dp[0][0]=0;
11         for(int i=1;i<=n;i++)
12         {
13             dp[i][1]=max(dp[i-1][1],dp[i-1][0]-w[i-1]);
14             dp[i][0]=max(dp[i-1][0],dp[i-1][2]);
15             dp[i][2]=dp[i-1][1]+w[i-1];
16         }
17         return max(dp[n][2],dp[n][0]);
18 
19     }
20 };
View Code

 

posted @ 2021-01-08 17:27  canwinfor  阅读(7)  评论(0)    收藏  举报