http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1422
https://vjudge.net/problem/LightOJ-1422
这题不就是给你一个目标序列,每个数字代表一种颜色,你有一把刷子每次能刷连续的一段,要你从空序列刷成目标序列那道题?
若 c[i]==c[j] c [ i ] == c [ j ] f[i][j]=f[i][j−1] f [ i ] [ j ] = f [ i ] [ j − 1 ]
否则 f[i][j]=min{f[i][k]+f[k+1][j]} f [ i ] [ j ] = m i n { f [ i ] [ k ] + f [ k + 1 ] [ j ] }
//DP
#include
#include
#include
#include
#define maxn 110
#define int_inf 0x3f3f3f3
using namespace std;
int c[maxn], f[maxn][maxn], N;
int read(int x=0)
{
char c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-48;
return f*x;
}
int init()
{
int i, t=0;
N=read();
if(!N)return 0;
for(i=1;i<=N;i++)c[i]=read();
return 1;
}
void dp()
{
int l, i, j, k;
for(i=1;i<=N;i++)f[i][i]=1;
for(l=2;l<=N;l++)for(i=1;i+l-1<=N;i++)
{
j=i+l-1;
f[i][j]=int_inf;
for(k=i+1;k<=j;k++)f[i][j]=min(f[i][j],f[i][k-1]+f[k][j]);
if(c[i]==c[j])f[i][j]=min(f[i][j],f[i+1][j]);
}
printf("%d\n",f[1][N]);
}
int main()
{
int c=0, T;
T=read();
while(T--)init(), printf("Case %d: ",++c), dp();
return 0;
}