区间DP
题目描述
开始你有一个空白字符串,每次可以选择一段区间[l,r]进行涂色,问最少涂色几次会形成字符串s。
注意:涂色会覆盖。
样例输入:
AABCBA
样例输出
3
这是区间dp比较经典的一个写法。
memset(dp,inf,sizeof(dp))//初始dp数组
for(int len=2;len<=n;len++){//枚举区间长度
for(int i=1;i<n;++i){//枚举区间的起点
int j=i+len-1;//根据起点和长度得出终点
if(j>n) break;//符合条件的终点
for(int k=i;k<=j;++k)//枚举最优分割点
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+w[i][j]);//状态转移方程
}
}
下面是本题的代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
typedef long long ll;
const int inf=0x3f3f3f3f;
int n;
string s;
int dp[100][100];
int main() {
cin>>s;
n=s.length();
memset(dp,0x5f,sizeof(dp));
for(int i=0; i<n; i++)
dp[i][i]=1;
for(int j=2; j<=n; j++) {
for(int i=0; i<=n-j; i++) {
int x=i,y=i+j-1;
if(s[x]==s[y])dp[x][y]=min(dp[x][y-1],dp[x+1][y]);
for(int k=x; k<y; k++)
dp[x][y]=min(dp[x][y],dp[x][k]+dp[k+1][y]);
}
}
printf("%d\n",dp[0][n-1]);
return 0;
}