bzoj1260 [CQOI2007]塗色paint

題目鏈接:bzoj1260
題目大意:
有一塊長度爲n的木板,初始時沒有塗過任何顏色。每次可以把一段連續的木版塗成一個給定的顏色,後塗的顏色覆蓋先塗的顏色。給一個目標狀態,問達到目標的最少的塗色次數。

題解:
區間dp
f[i][j] 表示i到j之間弄好需要的最少次數
從小到大枚舉範圍
若第i 格跟第j 格的目標狀態相同,則有

f[i][j]=min(f[i+1][j],f[i][j1],f[i+1][j1]+1)

否則枚舉中間的斷點,f[i][j]=min(f[i][k]+f[k+1][j])

雖然很簡單,但我還是…QwQ

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int f[60][60];//start-end
int mymin(int x,int y){return (x<y)?x:y;}
int main()
{
    //freopen("a.in","r",stdin);
    //freopen("a.out","w",stdout);
    char s[60];gets(s+1);
    int n,i,l,cnt;
    n=strlen(s+1);cnt=0;
    memset(f,63,sizeof(f));
    for (i=1;i<=n;i++) f[i][i]=1;
    for (l=2;l<=n;l++)//length
     for (i=1;i<=n;i++)//start
     {
         int j=i+l-1;
         if (s[i]==s[j])
         {
             f[i][j]=mymin(f[i+1][j],f[i][j-1]);
             f[i][j]=mymin(f[i][j],f[i+1][j-1]+1);
         }else
         {
             for (int k=i;k<j;k++)
              f[i][j]=mymin(f[i][j],f[i][k]+f[k+1][j]);
         }
     }
    printf("%d\n",f[1][n]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章