动态规划_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

 

时间限制: 10 s
空间限制: 256000 KB
题目等级 : 黄金 Gold
 
 
 
 
 
题目描述 Description

在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分.

输入描述 Input Description

数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.

输出描述 Output Description

输出共2行,第1行为最小得分,第2行为最大得分.

样例输入 Sample Input

4
4 4 5 9

样例输出 Sample Output

43
54

数据范围及提示 Data Size & Hint

经典的区间动态规划。

分析


枚举起点即可.

 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 }
View Code

 

以上是关于动态规划_20230412的主要内容,如果未能解决你的问题,请参考以下文章

算法导论_第十六章_动态规划_creatshare分享会

算法思想__动态规划

递归 动态规划

Codevs_2102_石子归并2_(划分型动态规划)

动态规划详解_2

算法导论_动态规划_最长公共子序列