dp专题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dp专题相关的知识,希望对你有一定的参考价值。

  因为自己dp比较垃圾,所以就开个坑来刷刷dp,大概希望在noip前能刷完吧。。

                                                                   
3/30

1.洛谷P1359 租用游艇 

题目链接:https://www.luogu.org/problem/show?pid=1359

这题很明显可以跑最短路233。

f[i]表示到第i个出租站的最少费用。

f[i]=min(f[i],f[j]+a[j][i]); f[j]+a[j][i]是从第j站到第i站

f[1]=0因为在第一个站开始走没有花费

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <stack>
 7 #include <cmath>
 8 #define ll long long
 9 #define out(a) printf("%d",a)
10 using namespace std;
11 int n;
12 int a[500][500];
13 int f[100000];
14 int main()
15 {
16     scanf("%d",&n);
17     for (int i=1;i<=n;i++)
18       for (int j=i+1;j<=n;j++)
19         scanf("%d",&a[i][j]);
20          memset(f,127,sizeof(f)); f[1]=0;
21     for (int i=2;i<=n;i++)
22       for (int j=1;j<i;j++)
23         f[i]=min(f[i],f[j]+a[j][i]);
24     out(f[n]); 
25 }
View Code

2.洛谷P2800 又上锁妖塔

题目链接:https://www.luogu.org/problem/show?pid=2800

算是比较水的dp了。

开两个数组一个flew[i]表示飞到第i层的最小时间,dp[i]表示走到第i层最小时间。

那么就有:flew[i]=min(dp[i-1],dp[i-2]); 从i-1层或i-2层飞到第i层(飞一次就要走一次)

 dp[i]=min(dp[i-1]+a[i],flew[i]+a[i]);(前一步是走上来和飞上来的情况)

那么答案就是min(flew[n],dp[n])了。

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <stack>
 7 #include <cmath>
 8 #include <vector>
 9 #include<functional>  
10 #define ll long long
11 #define out(a) printf("%d",a)
12 using namespace std;
13 int n;
14 int a[1000050],dp[1000050],flew[1000050];
15 int main()
16 {
17     scanf("%d",&n);
18     for (int i=1;i<=n;i++)
19       scanf("%d",&a[i]);
20     dp[1]=a[1];
21     for (int i=2;i<=n;i++) {
22         flew[i]=min(dp[i-1],dp[i-2]);
23         dp[i]=min(flew[i-1]+a[i],dp[i-1]+a[i]);
24     }
25     out(min(flew[n],dp[n]));
26 }
View Code

3.P2837 晚餐队列安排

题目链接:https://www.luogu.org/problem/show?pid=2837

这题不太会写啊然后无耻地翻了题解

dp[i][0]表示第i个数修改为1的最小操作

dp[i][1]表示第i个数修改为2的最小操作

那么a[i]==1时,则有dp[i][0]=dp[i-1][0]; dp[i][1]=min(dp[i-1][1],dp[i-1][0])+1;

a[i]==2同理==

答案就是min(dp[n],0,dp[n][1]);

 

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <stack>
 7 #include <cmath>
 8 #include <vector>
 9 #include<functional>  
10 #define ll long long
11 #define out(a) printf("%lld ",a)
12 using namespace std;
13 int n;
14 int a[100001];
15 int dp[100001][2];
16 int main()
17 {
18     scanf("%d",&n);
19     for (int i=1;i<=n;i++)
20       scanf("%d",&a[i]);
21       if (a[1]==2) dp[1][0]=1,dp[1][1]=0;
22       else dp[1][0]=0,dp[1][1]=1;
23     for (int i=2;i<=n;i++) {
24         if (a[i]==1) {
25             dp[i][0]=dp[i-1][0];
26             dp[i][1]=min(dp[i-1][0],dp[i-1][1])+1;
27         }
28         if (a[i]==2) {
29             dp[i][0]=dp[i-1][0]+1;
30             dp[i][1]=min(dp[i-1][0],dp[i-1][1]);
31             }
32         }
33     out(min(dp[n][1],dp[n][0]));
34 }
View Code

 

喂丸die续......

 




以上是关于dp专题的主要内容,如果未能解决你的问题,请参考以下文章

Kuangbin专题12 基础DP

UVA-624 dp专题A

UESTC 电子科大专题训练 DP-E

数位dp专题

区间dp专题练习

LeetCode dp专题