TYVJ1056

和环形石子合并一个德行的一道题,区间DP
唯一的区别在于计分方式,转移方程也有所不同
dp[i][j]表示合并i到j和能得到的最大的能量
dp[i][j] = max{f[i]*r[k]*r[j]+dp[i][k]+dp[k+1][j]|i<=k<j}
还有就是因为是环形的,所以当每次循环到n时就需要特殊处理了,数学功底不行,所以只能用笨法来一点一点处理了
dp目标dp[i][i-1]中的最大值
(dp[i][i-1]由来,dp[i][(i+n-1)%n]==dp[i][i-1])

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int maxn = 105;
 8 int f[maxn],r[maxn],dp[maxn][maxn];
 9 int main()
10 {
11     //freopen("in.txt","r",stdin);
12     int n;
13     cin>>n;
14     int t;
15     cin>>t;
16     f[1]=t;
17     for(int i = 2;i<=n;++i)
18     {
19         cin>>t;
20         r[i-1] = t;
21         f[i] = t;
22     }
23     r[n] = f[1];
24     memset(dp,0,sizeof(dp));
25     for(int s = 2;s<=n;++s)
26     {
27         for(int i = 1;i<=n;++i)
28         {
29             int j = s+i-1;
30             if(j<=n)for(int k = i;k<j;++k)
31                 dp[i][j]=max(dp[i][j],f[i]*r[k]*r[j] + dp[i][k] + dp[k+1][j]);
32             else
33                 for(int k = i;k<j;++k)
34                 {
35                     if(k<n)dp[i][j-n]=max(dp[i][j-n],f[i]*r[k]*r[j-n]+dp[i][k]+dp[k+1][j-n]);
36                     else if(k==n)dp[i][j-n]=max(dp[i][j-n],f[i]*r[k]*r[j-n]+dp[i][k]+dp[1][j-n]);
37                     else dp[i][j-n]=max(dp[i][j-n],f[i]*r[k-n]*r[j-n]+dp[i][k-n]+dp[k+1-n][j-n]);
38                 }
39         }
40     }
41     int ans = dp[1][n];
42     for(int i = 2;i<=n;++i)
43         ans=max(ans,dp[i][i-1]);
44     printf("%d\n",ans);
45     return 0;
46 }
时间: 2024-10-11 13:51:21

TYVJ1056的相关文章