P4170 [CQOI2007]涂色 CF607B Zuma ###K

题目链接:https://www.luogu.com.cn/problem/P4170

思路: 考虑合并两个区间的时候 如果首和尾相同的话

那么就可以在涂首的时候也涂上尾 或者是涂上尾的时候也涂上首

否则的话枚举分割点 取两段区间合并

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define pb push_back
 4 using namespace std;
 5 const int maxn=1e5+10;
 6 const int mod=1e9+7;
 7 int dp[100][100];
 8 
 9 
10 int main()
11 {
12     ios::sync_with_stdio(0);
13     cin.tie(0);
14     string s;
15     cin>>s;
16     int n=s.size();
17     for(int i=0;i<100;i++)
18         for(int j=0;j<100;j++)
19             dp[i][j]=1e9;
20     for(int i=1;i<=n;i++)
21         dp[i][i]=1;
22     for(int len=1;len<=n;len++)
23     {
24         for(int i=1;i+len-1<=n;i++)
25         {
26             int endx=i+len-1;
27             if(s[i-1]==s[endx-1])
28             {
29                 dp[i][endx]=min({dp[i][endx],dp[i+1][endx],dp[i][endx-1]});
30             }
31             else
32             {
33                 for(int j=i;j<endx;j++)
34                     dp[i][endx]=min(dp[i][endx],dp[i][j]+dp[j+1][endx]);
35             }
36         }
37     }
38     cout<<dp[1][n]<<'\n';
39 
40 }
View Code

 

类似的一题  不过要注意中间的不一定是回文串所以不一定最优  所以和上面不同,这里每次都要枚举断点

https://www.luogu.com.cn/problem/CF607B

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define pb push_back
 4 using namespace std;
 5 const int maxn=1e5+10;
 6 const int mod=1e9+7;
 7 int dp[555][555];
 8 int a[555];
 9 
10 
11 
12 int main()
13 {
14     ios::sync_with_stdio(0);
15     cin.tie(0);
16     int n;
17     cin>>n;
18     for(int i=1;i<=n;i++)
19         for(int j=1;j<=n;j++)
20                 dp[i][j]=1e9;
21     for(int i=1;i<=n;i++)
22     {
23         cin>>a[i];
24         dp[i][i]=1;
25     }
26     for(int len=2;len<=n;len++)
27     {
28         for(int i=1;i+len-1<=n;i++)
29         {
30             int j=i+len-1;
31             if(a[i]==a[j])
32             {
33                 if(len==2)
34                     dp[i][j]=1;
35                 else
36                     dp[i][j]=dp[i+1][j-1];
37             }
38             for(int k=i;k<j;k++)
39             {
40                 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
41             }
42         }
43     }
44     cout<<dp[1][n]<<'\n';
45 
46 
47 
48 }
View Code

 

posted @ 2020-12-19 01:01  canwinfor  阅读(82)  评论(0)    收藏  举报