从零开始的DP练习册

Posted shingen

tags:

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

此文为博主原创,转载时请通知博主,并把原文链接放在正文醒目位置。

因为我确实把DP忘得一干二净...就当新学了。无解析无责任,只贴题目来源和AC代码。

 

1.数字三角形

记忆化搜索还是很容易想的,这个代码是我早期的代码orz

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 //code by kamigen
 4 using namespace std;
 5 
 6 int num[1000][1000];
 7 
 8 int main()
 9 {
10     int r;
11     scanf("%d",&r);
12     for(int i = 1;i <= r;i ++)
13     {
14         for(int j = 1;j <= i;j ++)
15             scanf("%d",&num[i][j]);
16     }
17     for(int i = r-1;i > 0;i --)
18     {
19         for(int j = 1;j <= i+1;j ++)
20         {
21             num[i][j] += max(num[i+1][j],num[i+1][j+1]);
22         }
23     }
24     printf("%d",num[1][1]);
25     return 0;
26 } 
Number Triangles

 

2.USACO 邮票

完全背包。

技术分享图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 //code by kamigen
 6 inline void read(int &x)
 7 {
 8     char ch = getchar(),c = ch;x = 0;
 9     while(ch < 0 || ch >9) c = ch,ch = getchar();
10     while(ch <= 9 && ch >= 0) x = x*10+ch-0,ch = getchar();
11     if(c == -) x = -x;
12 }
13 
14 int dp[2000005],stamp[300],tot[300];
15 int k,n,mx,ans,V;
16 
17 inline int Max(int a,int b)
18 {return a>b?a:b;}
19 inline int Min(int a,int b)
20 {return a<b?a:b;}
21 
22 int main()
23 {
24     memset(dp,0x3f,sizeof(dp));
25     dp[0] = 0;
26     read(k),read(n);
27     for(int i = 1;i <= n;++ i)
28         read(stamp[i]),mx = Max(mx,stamp[i]);
29     V = mx*k;
30     for(int i = 1;i <= n;++ i)
31         for(int j = stamp[i];j <= V;++ j)
32             dp[j] = Min(dp[j],dp[j-stamp[i]]+1);
33     for(int i = 1;i <= V;++ i)
34         if(dp[i] <= k) ans ++;
35         else break;
36     printf("%d\n",ans);        
37     return 0;
38 }
Stamps

 

3.USACO 赚钱

完全背包。 不知道为什么这题好冷啊...我给它写了个题解。

技术分享图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 //code by kamigen
 6 inline void read(int &x)
 7 {
 8     char ch = getchar(),c = ch;x = 0;
 9     while(ch < 0 || ch >9) c = ch,ch = getchar();
10     while(ch <= 9 && ch >= 0) x = x*10+ch-0,ch = getchar();
11     if(c == -) x = -x;
12 }
13 
14 int n,m,tmp,ans;
15 int w[110],val[110],dp[100005];
16 
17 inline int Max(int a,int b)
18 {return a>b?a:b;}
19 
20 int main()
21 {
22     read(n),read(m);
23     for(int i = 1;i <= n;++ i)
24     {
25         read(w[i]),read(tmp);
26         val[i] = tmp-w[i];
27     }
28     //dp[i]表示花费i元买古董的最大利润 
29     for(int i = 1;i <= n;++ i)
30         for(int j = w[i];j <= m;++ j)
31             dp[j] = Max(dp[j],dp[j-w[i]]+val[i]);
32     for(int i = 1;i <= m;++ i)
33         ans = Max(ans,dp[i]-i+m);
34     printf("%d\n",ans);
35     return 0;
36 }
Making Money

 

4.openjudge 开餐馆

一个普通的、略有难度(对我来说)的DP。

技术分享图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 //code by kamigen
 6 inline void read(int &x)
 7 {
 8     char ch = getchar(),c = ch;x = 0;
 9     while(ch < 0 || ch >9) c = ch,ch = getchar();
10     while(ch <= 9 && ch >= 0) x = x*10+ch-0,ch = getchar();
11     if(c == -) x = -x;
12 }
13 
14 int t,n,k,last,ans;
15 int dis[110],p[110],dp[110];
16 
17 inline int Max(int a,int b)
18 {return a>b?a:b;}
19 
20 int main()
21 {
22     read(t);
23     while(t --)
24     {
25         memset(dp,0,sizeof(dp));
26         read(n),read(k);
27         for(int i = 1;i <= n;++ i)
28             read(dis[i]);
29         for(int i = 1;i <= n;++ i)
30             read(p[i]);
31         for(int i = 1;i <= n;++ i)
32         {
33             for(int j = 1;j <= i;++ j)
34                 if(dis[i]-dis[j] > k)
35                     dp[i] = Max(dp[i],dp[j]);
36             dp[i] += p[i];
37         }        
38         ans = 0;
39         for(int i = 1;i <= n;++ i)
40             ans = Max(dp[i],ans);
41         printf("%d\n",ans);
42     }
43     return 0;
44 }
restaurant

 

5.openjudge 计算字符串距离

一个普通的、略有难度(对我来说)的DP。

技术分享图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 //code by kamigen
 6 inline void read(int &x)
 7 {
 8     char ch = getchar(),c = ch;x = 0;
 9     while(ch < 0 || ch >9) c = ch,ch = getchar();
10     while(ch <= 9 && ch >= 0) x = x*10+ch-0,ch = getchar();
11     if(c == -) x = -x;
12 }
13 
14 int t,l,r,len1,len2;
15 int dp[1010][1010];
16 //dp[i][j]表示s1前i位与s2前j位的距离
17 char s1[1010],s2[1010]; 
18 
19 inline int Min(int a,int b)
20 {return a<b?a:b;}
21 
22 inline int Max(int a,int b)
23 {return a>b?a:b;}
24 
25 int main()
26 {
27     read(t);
28     while(t --)
29     {
30         scanf("%s",s1+1);
31         scanf("%s",s2+1);
32         memset(dp,0,sizeof(dp));
33         len1 = strlen(s1+1),len2 = strlen(s2+1);
34         for(int i = 1;i <= len1;++ i) dp[i][0] = i;
35         for(int i = 1;i <= len2;++ i) dp[0][i] = i;
36         for(int l = 1;l <= len1;++ l)
37             for(int r = 1;r <= len2;++ r)
38             {
39                 if(s1[l] == s2[r]) dp[l][r] = dp[l-1][r-1];
40                 else
41                     dp[l][r] = Min(dp[l-1][r],Min(dp[l-1][r-1],dp[l][r-1]))+1;            
42             }
43         printf("%d\n",dp[len1][len2]);
44     }
45     return 0;
46 }
string distance

 

6.openjudge 最低通行费

坐标模型,比4和5简单多了。

技术分享图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 //code by kamigen
 6 inline void read(int &x)
 7 {
 8     char ch = getchar(),c = ch;x = 0;
 9     while(ch < 0 || ch >9) c = ch,ch = getchar();
10     while(ch <= 9 && ch >= 0) x = x*10+ch-0,ch = getchar();
11     if(c == -) x = -x;
12 }
13 
14 int n;
15 int mp[110][110],dp[110][110];
16 
17 inline int Min(int a,int b)
18 {return a<b?a:b;}
19 
20 int main()
21 {
22     read(n);
23     for(int i = 1;i <= n;++ i)
24         for(int j = 1;j <= n;++ j)
25             read(mp[i][j]);
26     memset(dp,0x3f,sizeof(dp));
27     dp[0][0] = 0,dp[0][1] = 0,dp[1][0] = 0;
28     for(int i = 1;i <= n;++ i)
29         for(int j = 1;j <= n;++ j)
30             dp[i][j] = Min(dp[i-1][j],dp[i][j-1])+mp[i][j];
31     printf("%d\n",dp[n][n]);
32     return 0;
33 }
tolls

 

7.等待更新

以上是关于从零开始的DP练习册的主要内容,如果未能解决你的问题,请参考以下文章

从零开始配置vim(27)——代码片段

从零开始配置vim(27)——代码片段

《从零开始学Swift》同步练习题解析-关东升-专题视频课程

re:从零开始的数位dp

如何从零开始集成DTM Android SDK

从零开始一起学习SLAM | 掌握g2o顶点编程套路