动态规划类题目解题步骤:
1、定义数组元素的含义
2、找出数组元素之间的关系式
3、找出初始值
1.最大序列和
给出一个整数序列S,其中有N个数,定义其中一个非空连续子序列T中所有数的和为T的“序列和”。 对于S的所有非空连续子序列T,求最大的序列和。 变量条件:N为正整数,N≤1000000,结果序列和在范围(-2^63,2^63-1)以内。
#includeusing namespace std; int main(){ int n; while(cin>>n){ int pos = 0; long long dp[n]; long long num; int len = n; while(n--){ cin>>num; dp[pos] = num; pos++; } for(int i=1;i 2.最长连续公共子序列
输入两个字符串s1,s2。输出最长连续公共子串长度和最长连续公共子串。
#includeusing namespace std; int dp[101][101]; int main(){ string s1,s2; while(cin>>s1>>s2){ int len1 = s1.size(); int len2 = s2.size(); for(int i=0;i<=len1;i++){ dp[i][0] = 0; } for(int j=0;j<=len2;j++){ dp[0][j] = 0; } int max_len = 0; int ri; for(int i=1;i<=len1;i++){ for(int j=1;j<=len2;j++){ if(s1[i-1]==s2[j-1]){ dp[i][j] = dp[i-1][j-1]+1; if(dp[i][j]>=max_len){ max_len=dp[i][j]; ri = i; } }else{ dp[i][j] = 0; } } } cout< 3.最长公共子序列
输入两个字符串s1,s2。输出最长连续公共子串长度和最长连续公共子串。
与上题只有两个区别,其一是s1[i-1]不等于s2[j-1]后的处理,其二是此时dp数组的最大值一定出现在dp[len1][len2],不需要再判断和记录。
#includeusing namespace std; int dp[1001][1001]; int main(){ string s1,s2; while(cin>>s1>>s2){ int len1 = s1.size(); int len2 = s2.size(); for(int i=0;i<=len1;i++){ dp[i][0] = 0; } for(int j=0;j<=len2;j++){ dp[0][j] = 0; } for(int i=1;i<=len1;i++){ for(int j=1;j<=len2;j++){ if(s1[i-1]==s2[j-1]){ dp[i][j] = dp[i-1][j-1]+1; }else{ dp[i][j] = max(dp[i-1][j],dp[i][j-1]); } } } cout< 4.字符串编辑距离
易错点:每次求dp[i][j]比较的是s1[i-1]和s2[j-1],因为dp数组的i/j与字符串的i/j含义不同,前者是指长度,后者是指第i位字符,长度为i的字符串的字符序号是i-1,因为是从0开始标号。
#includeusing namespace std; int dp[1001][1001]={0}; //长度为i的s1,转化为长度为j的s2,共需要多少步 int main(){ string s1,s2; cin>>s1>>s2; int len1 = s1.size(); int len2 = s2.size(); // i=0时,只能对s1进行插入操作 for(int j = 1;j<=len2;j++){ dp[0][j] = dp[0][j-1] + 1; } // j=0时,只能对s2进行删除操作 for(int i = 1;i<=len1;i++){ dp[i][0] = dp[i-1][0] + 1; } for(int i = 1;i<=len1;i++){ for(int j = 1;j<=len2;j++){ if(s1[i-1]==s2[j-1]){ dp[i][j] = dp[i-1][j-1]; }else{ dp[i][j] = min(min(dp[i-1][j-1],dp[i][j-1]),dp[i-1][j])+1; } } } cout<


![[N诺] 动态规划算法练习题合集 [N诺] 动态规划算法练习题合集](http://www.mshxw.com/aiimages/31/1012691.png)
