1. 程式人生 > >[hdu2476]String painter(區間dp)

[hdu2476]String painter(區間dp)

感覺自己發兩篇一樣的題解不太好

 CQOI2007 塗色 paint (區間dp)

沒錯就是前兩天我閒得無聊發的這道題

只不過初始條件變了...

這道題初始木棍已經是塗過色的了...

然後我就又不會了

(那你為啥還在這兒發題解)

既然已經有初始顏色了,那麼就說明有的地方會是不需要塗的(因為本來就是目標顏色)

那麼相較於上面那道題的修改就在這裡了

1 for(int i=1;i<=n;i++)
2     {
3         if(xl1[i]==xl2[i])dp2[i]=dp2[i-1];
4         else for(int k=0;k<i;k++)dp2[i]=min(dp2[i],dp2[k]+dp[k+1
][i]); 5 }

我想還是挺好懂的

事實上本質就是再額外從頭到尾dp一次...

只是如果某一格已經是原來的顏色那麼塗完它前面所有格子就等同於多塗了它這一個格子

然後就又沒了

#include<cstdio>
#include<cstring>
int min(int a,int b){return a<b?a:b;}
char in1[520],in2[520];
int xl1[520],xl2[520];
int dp[520][520],dp2[520];
int main()
{
while(scanf("%s%s",in1,in2)!=EOF)
{
    memset(dp,
0x3f,sizeof(dp)); memset(dp2,0x3f,sizeof(dp2)); dp2[0]=0; memset(xl1,0,sizeof(xl1)); memset(xl2,0,sizeof(xl2)); // scanf("%s",in2); int n=strlen(in1); for(int i=0;i<=n+1;i++)dp[i][i]=1; for(int i=0;i<n;i++) { xl1[i+1]=in1[i]; xl2[i+1]=in2[i]; }
for(int d=1;d<n;d++) { for(int i=1;i+d<=n;i++) { if(xl2[i]==xl2[i+d])dp[i][i+d]=min(dp[i][i+d-1],dp[i+1][i+d]); for(int k=i;k<i+d;k++)dp[i][i+d]=min(dp[i][i+d],dp[i][k]+dp[k+1][i+d]); } } // printf("%d\n",dp[1][n]); for(int i=1;i<=n;i++) { if(xl1[i]==xl2[i])dp2[i]=dp2[i-1]; else for(int k=0;k<i;k++)dp2[i]=min(dp2[i],dp2[k]+dp[k+1][i]); } printf("%d\n",dp2[n]); } return 0; }