窝药蜂辣:( 感觉dp难在咋转成数组,例如将字符串str1(len=i)转换为str2(len1=j),可以进行删除,改动,添加操作,使用dp的方法就是写一个数组记录需要操作数例如a[2][2]就是str1前两位和str2前两位转化成相同的所需要的步数,真嘞很奇妙嘿
那个对刚学的窝有点难....
下次一定(这次来个简单的
P1216 [IOI 1994] 数字三角形 Number Triangles - 洛谷
dp实质是牺牲空间时间,达到全局最优,所以遇到这样的题肯定是要用dp了,更入门的题是n*n的方格阵从左上走到右下一共有多少种方式,并且每次只能向右或向下,那个就是dp[i][j]=dp[i-1][j]+dp[i][j-1],同样也要初始化,因为只能往两个方向走,所有从起点走到最右边和最下边的路径数都是1,就可以使用dp求出到达dp[n][n]的路径数
在该题目中初始化我是就按他的方向来了
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
{
cin>>arr[i][j];
}
dp[1][1]=arr[1][1];
for(int i=2;i<=n;i++)
{
dp[i][1]=dp[i-1][1]+arr[i][1];
}
for(int i=2;i<=n;i++)
{
dp[i][i]=dp[i-1][i-1]+arr[i][i];
}
dp数组用来存储改动后数据,arr则是原数据,动态规划要满足全局最优,在该题中从头行到末行,反正有好多条路达到,比如到达第三行时7-->3-->1和7-->8-->1那肯定是前者更优,那么7-->8-->1这条路后面的分支就全嗝屁了,因为7-->8那条路可以走的7-->3也可以走,而且已经知道更好了,越往上的点排除的路越多,dp就是找到最好的一条路。
嗷插播个也是入门些的:)
务必忽略我的字体:):):):):):)
懂了上面的那个题这个题也是同理嘞,但是一个那个下部分的分支会变少,这个会越变越多,没事,找规律,可以相当于上面3*3数组放大再砍一半嘛
我的实际图就为标准输入的样子
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
设想图为
7 8 0 4 5
3 1 4 6
8 7 2
2 5
4
其实要是和设想图一样就和上面的题一模一样了只不过循环条件变一下,但是也还是有规律可寻找的例如设想数组中取1的上和左的最小值,设想图的上和右实际是实际图的上和左上。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int arr[n+1][n+1];
int dp[n+1][n+1];
memset(arr,-1,sizeof(arr));
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
{
cin>>arr[i][j];
}
dp[1][1]=arr[1][1];
for(int i=2;i<=n;i++)
{
dp[i][1]=dp[i-1][1]+arr[i][1];
}
for(int i=2;i<=n;i++)
{
dp[i][i]=dp[i-1][i-1]+arr[i][i];
}
int max=1;
for(int i=3;i<=n;i++)
for(int j=2;j<=i-1;j++)
{
dp[i][j]=dp[i-1][j]>dp[i-1][j-1]?dp[i-1][j]:dp[i-1][j-1];
dp[i][j]+=arr[i][j];
if(dp[i][j]>max)
max=dp[i][j];
}
cout<<max;
}
:)下次争取把那个字符串的再弄明白点