动态规划_20230412
Posted xccx-0824
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划_20230412相关的知识,希望对你有一定的参考价值。
115、不同的子序列
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)
解题思路:
序列初始化自然是用空字符串分别和s和t去比较进行初始化,最终的状态即是dp[s.length()][t.length]
,出现0的情况是可能的(根本没出现过)
当s[i - 1] != s[j - 1]
时,很明显从之前的状态dp[i - 1][j]
继承下来就可以。但是当两者相等的时候,除了从dp[i - 1][j - 1]
继承下来之外,依然要考虑dp[i - 1][j]
,因为可以不用s[i - 1],因此dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
72、编辑距离
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
示例 1:
输入:word1 = "horse", word2 = "ros" 输出:3
解释: horse -> rorse (将 \'h\' 替换为 \'r\') rorse -> rose (删除 \'r\') rose -> ros (删除 \'e\')
解题思路:
三种操作分别对应着三个状态(此处以s变成t的视角,s纵t横),然后在此基础上加一(操作)
-
插入:
dp[i - 1][j]
-
删除:
dp[i][j - 1]
-
替换:
dp[i - 1][j - 1]
如果s[i - 1] != t[j - 1]
时则以上三种情况取最小值即可
如果相等则继承dp[i - 1][j - 1]
即可,不能用Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1]))
,因为dp[i][j - 1]
可能比dp[i - 1][j - 1]
还小
Codevs_2102_石子归并2_(划分型动态规划)
描述
http://codevs.cn/problem/2102/
2102 石子归并 2
分析
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=100+5,INF=0x7fffffff; 5 6 int n,ans1,ans2; 7 int s[maxn<<1],dp1[maxn][maxn],dp2[maxn][maxn]; 8 9 void solve(){ 10 ans1=INF, ans2=-INF; 11 for(int q=1;q<=n;q++){ 12 for(int r=2;r<=n;r++) 13 for(int i=q;i<=q+n-r;i++){ 14 int j=i+r-1; 15 dp1[i-q+1][j-q+1]=INF; dp2[i-q+1][j-q+1]=-INF; 16 for(int k=i;k<j;k++){ 17 dp1[i-q+1][j-q+1]=min(dp1[i-q+1][j-q+1],dp1[i-q+1][k-q+1]+dp1[k+1-q+1][j-q+1]+s[j]-s[i-1]); 18 dp2[i-q+1][j-q+1]=max(dp2[i-q+1][j-q+1],dp2[i-q+1][k-q+1]+dp2[k+1-q+1][j-q+1]+s[j]-s[i-1]); 19 } 20 } 21 ans1=min(dp1[1][n],ans1); 22 ans2=max(dp2[1][n],ans2); 23 } 24 printf("%d\\n%d\\n",ans1,ans2); 25 } 26 void init(){ 27 scanf("%d",&n); 28 for(int i=1;i<=n;i++){ 29 int t; scanf("%d",&t); 30 s[i]=s[i-1]+t; 31 } 32 for(int i=n+1;i<=n*2;i++) s[i]=s[i-n]+s[n]; 33 } 34 int main(){ 35 init(); 36 solve(); 37 return 0; 38 }
以上是关于动态规划_20230412的主要内容,如果未能解决你的问题,请参考以下文章