从零开始的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.等待更新

原文地址:https://www.cnblogs.com/shingen/p/8830440.html

时间: 2024-10-15 00:46:26

从零开始的DP练习册的相关文章

re:从零开始的数位dp

起源:唔,,前几天打cf,edu50那场被C题虐了,决定学学数位dp,此文持续更新,9.16号之前会更新完的. ps:我也什么都不会遇到一些胡话大家不要喷我啊... 数位dp问题:就是求在区间l到r上满足规定条件的数的个数. ex1:hdu3555 题意:给你n,求从一到n中有多少个数不包含"49".(t<=1e4,n<=2^63-1) 首先数位dp顾名思义就是对数位进行dp嘛,所以dp数组的第一维我们用来保存数字的位数,第二位我们用来判定当前位是否为4, 所以就是  dp

codevs 3342 绿色通道 (二分+线性DP)

codevs 3342 绿色通道 http://codevs.cn/problem/3342/ 难度等级:黄金 题目描述 Description <思远高考绿色通道>(Green Passage, GP)是唐山一中常用的练习册之一,其题量之大深受lsz等许多oiers的痛恨,其中又以数学绿色通道为最.2007年某月某日,soon-if (数学课代表),又一次宣布收这本作业,而lsz还一点也没有写…… 高二数学<绿色通道>总共有n道题目要写(其实是抄),编号1..n,抄每道题所花时间

NOJ 2033 一页书的书 (组合数+dp)

一页书的书 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte 总提交 : 55            测试通过 : 12  题目描述 一页书前辈作为一位得道高僧,在他无悔的生涯中创作了许多经典,被世人称作百世经纶.这一天有m个粉丝来膜拜书大,书大很开心,决定送他们每人一本经典.已知一页书一共创作了n部作品,每部作品分别有a1.a2-an份藏本,那么书大一共可以有多少种送书的选择呢?(由于计算结果可能很大,请把结果对100

topcoder-srm701-div2-900 博弈\计算二进制位1的个数\dp\状态压缩

借用一下qls翻译过来的题面 现在有 n 个石子,A 和 B 轮流取石子,A先,每次最多可以取 m 个石子,取到最后一个石子的人获胜,但是某个人如果取完石子时候剩余石子数的二进制表示中有奇数个1,这个人就输了给定 n 和 m,问谁赢n<=5e8, m<=50TL 2s 以前我是从来没接触过博弈的 首先普及一下博弈的基本知识.. 必胜态,必败态,以及必胜点与必败点 首先有一个字必须要看清楚,那就是"必"字 是必胜而不是,胜利就行,这个字很关键 如图所示,一个点是p-posit

【读书笔记-《Android游戏编程之从零开始》】8.Android 游戏开发常用的系统控件(系统控件常见问题)

Android 中常用的计量单位Android有时候需要一些计量单位,比如在布局Layout文件中可能需要指定具体单位等.常用的计量单位有:px.dip(dp).sp,以及一些不常用的pt.in.mm.下面详细介绍下这些计量单位之间的区别和联系.in:英寸(长度单位):mm:毫米(长度单位):pt:磅/点,1/72英寸(一个标准的长度单位):sp:全名 scaled pixels-best for text size,放大像素,与刻度无关,可以根据用户的字体大小就行缩放,主要用来处理字体的大小:

从零开始学Xamarin.Forms(一) 概述

Xamarin 读 "?z?m?rin",是一个基于开源项目mono的能够使用C#开发的收费的跨平台(iOS.Android.Windows Phone.Mac)解决方案. 1.原理 Xamarin.iOS: 也就是之前的 MonoTouch(Mono for iOS),使?静态编译(Ahead-Of-Time)?式将C#代码编译为 ARM?进制代码. Xamarin.Android: 即之前的MonoDroid(Mono for Android) ,是将C# 代码编译成IL封装到Mo

单调队列优化dp题目

附一链接,大多题型里面有,再附两题:https://blog.csdn.net/hjf1201/article/details/78729320 1.绿色通道 题目描述 Description <思远高考绿色通道>(Green Passage, GP)是唐山一中常用的练习册之一,其题量之大深受lsz等许多oiers的痛恨,其中又以数学绿色通道为最.2007年某月某日,soon-if (数学课代表),又一次宣布收这本作业,而lsz还一点也没有写-- 高二数学<绿色通道>总共有n道题目

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往