洛谷 P3146 [USACO16OPEN]248 G(区间dp)

传送门


解题思路

用dp[i][j]表示dp[i][j]能否合成一个数,负无穷表示合不成,否则即为合成的数。

然后枚举k,很显然,如果dp[i][k]==dp[k+1][j],dp[i][j]就可以从前面两个转化过来。

最后对所有的任意长度的区间取一个max。

AC代码

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include
 6 using namespace std;
 7 const int maxn=250;
 8 int n,a[maxn],dp[maxn][maxn],ans;
 9 int main()
10 {
11     cin>>n;
12     memset(dp,-0x3f,sizeof(dp));
13     for(int i=1;i<=n;i++) cin>>a[i];
14     for(int i=1;i<=n;i++) dp[i][i]=a[i];
15     for(int len=2;len<=n;len++){
16         for(int i=1;i<=n;i++){
17             int j=i+len-1;
18             if(j>n) break;
19             for(int k=i;k){
20                 if(dp[i][k]==dp[k+1][j])dp[i][j]=max(dp[i][j],dp[i][k]+1);
21             }
22         }
23     }
24     for(int i=1;i<=n;i++)
25         for(int j=1;j<=n;j++) ans=max(ans,dp[i][j]);
26     cout<<ans;    
27     return 0;
28 }

 

你可能感兴趣的:(洛谷 P3146 [USACO16OPEN]248 G(区间dp))