dp[2019.5.25]_2
1、对于长度相同的2个字符串A和B,其距离定义为相应位置字符距离之和。2个非空格字符的距离是它们的ASCII码之差的绝对值。空格与空格的距离为0,空格与其他字符的距离为一定值k。
在一般情况下,字符串A和B的长度不一定相同。字符串A的扩展是在A中插入若干空格字符所产生的字符串。在字符串A和B的所有长度相同的扩展中,有一对距离最小的扩展,该距离称为字符串A和B的扩展距离。
算法要求如下:
1、 数据输入:第1行是字符串A,第2行是字符串B,第3行是空格与其他字符的距离定值k。
2、 输出:字符串A和B的扩展距离。
Input:
cmc
snmn
2
Output:
10
注:设字符串A和B的子串A[1..i]和B[1..j]的扩展距离为val(i,j),则val(i,j)具有最优子结构性质,递归定义为:val(i,j)=min{val(i-1,j)+k, val(i,j-1)+k, val(i-1,j-1)+dist(ai,bj)}
dp思想:
将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
Code:
#include <bits/stdc++.h> using namespace std; const int maxn=5000; int dp[maxn][maxn]; string s,k; int dist(int i,int j) { int p1=s[i-1]-'a'; int p2=k[j-1]-'a'; return abs(p1-p2); } int main() { memset(dp,0,sizeof(dp)); cin>>s>>k; int t; cin>>t; int len = max(s.size(),k.size()); memset(dp,0,sizeof(dp)); for(int i=1;i<=s.size();i++) { dp[i][0]=t*i; } for(int i=1;i<=k.size();i++) { dp[0][i]=t*i; } for(int i=1;i<=s.size();i++) { for(int j=1;j<=k.size();j++) { dp[i][j]=min(dp[i-1][j-1]+dist(i,j),min(dp[i-1][j]+t,dp[i][j-1]+t)); } } int len1=s.size(); int len2=k.size(); cout<<dp[len1][len2]<<endl; return 0; }
2、在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径。 三角形的行数大于1小于等于100,数字为0~99。
Input:
5 //表示三角形的行数 接下来输入三角形
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Output:
30
dp基本思想:
将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
Code:
#include <bits/stdc++.h> using namespace std; #define Max 101 int D[Max][Max]; int n; int maxSum[Max][Max]; int MaxSum(int i,int j) { if(maxSum[i][j]!=-1) return maxSum[i][j]; if(i==n) maxSum[i][j]=D[i][j]; else { int x=MaxSum(i+1,j); int y=MaxSum(i+1,j+1); maxSum[i][j]=max(x,y)+D[i][j]; } return maxSum[i][j]; } int main() { int i,j; cin>>n; for(i=1;i<=n;i++) for(j=1;j<=i;j++) { cin>>D[i][j]; maxSum[i][j]=-1; } cout<<MaxSum(1,1)<<endl; return 0; }