Codeforces607B Zuma
题面:
一串数字,每次消去一个回文的子串需要花费一单位的时间,问把整个数字串消去最少需要多少单位时间。
解题过程:
- 开始写的区间DP在消去某些子串后产生新回文子串后无法处理
对于长度为一的串,初始需要一的时间。状态转移的时候:
*F[ l ][ r ] = 1 + F [l +1][ r ]
*F[ l ][ r ] = min { F[ l ][ k-1 ] + f[ k+1 ][ r ] } ( k处数字和 l 处数字相同)(当k == l+1时,k-1 == l ,即有三段 [ l, l] , [ l+1 ,l+1 ] ,[l +2 ][ r ] ,因为 a[ l ] = a[ k ] = a[ l +1] , 所以此时消去需要 1 + F [ l +2][ r ] 的时间)参考博客:https://blog.csdn.net/codebattle/article/details/50396982
参考题解:http://codeforces.com/blog/entry/22256
AC代码:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,p) for(int i=l;i<=p;i++)
#define fread() freopen("in.txt","r",stdin)
typedef long long ll;
typedef pair<int,int> P;
#define Fi first
#define Se second
#define mp make_pair
int n;
int a[1005];
int f[1005][1005];
int main(int argc, char const *argv[])
{
//fread();
ios::sync_with_stdio(false);
cin >> n;
rep(i,1,n) {
cin >> a[i];
f[i][i] =1;
// rep(j,i+1,n) f[i][j] = j-i+1;
}
for(int len=2;len<=n;len++){
for(int l=1;l<=n-len+1;l++){
int r = l+len-1;
f[l][r] = 1+f[l+1][r];
if(a[l] == a[l+1]) f[l][r] = min(f[l][r],f[l+2][r]+1);
for(int k=l+2;k<=r;k++){
if(a[l] == a[k]){
f[l][r] = min(f[l][r],f[l+1][k-1]+f[k+1][r]);
}
}
}
}
cout << f[1][n] <<endl;
}