原题地址:http://www.rqnoj.cn/problem/5
解题思路:
今天刚刚才知道了区间DP。。Orz。。本来以为是状态压缩DP,后来看到数据量才发现原来不是。后来参考了别人的题解。自己整理了思路:
问题现在变成从一堆数里面按某个顺序取走一些数,每次取走一个数的时候会得到能量,求最大能获得的能量。
由于是环状的,先将序列延长一倍,第n个数字等于第0个数字,第n+1个数字为第1个数字...依次类推。
a[i]表示第i个数
状态表示:
DP[i][j]表示在区间[i,j]中,除了a[i]之外的其他数都取走的最大的能量。(即最后留下的数是a[i])那么最后要求的答案就是假设最后剩下的是a[i](0<=i<n)这n中情况中的的最大值。
初始状态:DP[i][j]=0。
状态转移方程:DP[i][j]=max{ a[i]*a[k+1]*a[j+1]+DP[i][k]+DP[k+1][j] } (i<=k<j)
解题代码:
1 #include<stdio.h> 2 #include<iostream> 3 using namespace std; 4 int a[205],dp[205][205]={0}; 5 int Max(int a,int b) 6 { 7 return a>b?a:b; 8 } 9 int main() 10 { 11 int n,i,j,k; 12 scanf("%d",&n); 13 for(i=0;i<n;i++) 14 { 15 scanf("%d",&a[i]); 16 a[i+n]=a[i]; 17 } 18 for(j=0;j<2*n-1;j++) 19 { 20 for(i=j;i>j-n&&i>=0;i--) 21 { 22 for(k=i;k<j;k++) 23 { 24 dp[i][j]=Max(a[i]*a[k+1]*a[j+1]+dp[i][k]+dp[k+1][j],dp[i][j]); 25 } 26 } 27 } 28 int ans=0; 29 for(i=0;i<n;i++) 30 { 31 ans=Max(ans,dp[i][i+n-1]); 32 } 33 printf("%d ",ans); 34 return 0; 35 }