Codeforces607B Zuma 区间DP

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; 


}

猜你喜欢

转载自blog.csdn.net/Hagtaril/article/details/81393722