首页 > 代码库 > TYVJ1088
TYVJ1088
区间DP
设状态dp[i][j]表示左边取i个右边取j个所能得到的最大值
dp[i][j]只可能由两个状态得到:由dp[i-1][j]再取左边一个或者由dp[i][j-1]再取右边一个则状态方程有了:
dp[i][j] = max(dp[i-1][j]+r*a[i],dp[i][j-1]+r*a[n-j+1])
r是区间半径,即此刻要左边取的+右边取的==r i+j=r;
初始化dp[0][j]和dp[i][0]这个没什么好说的。。。。
最后遍历一遍dp中i+j==n的值取出最大值即为ans
感想:
dp真是让人无奈,无力,这特么跟本想不到的东西,就让人家说的非常简单。。。。。唉,向着dp 200题继续刷吧
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 2005; 7 int dp[maxn][maxn],a[maxn]; 8 int main() 9 {10 //freopen("in.txt","r",stdin);11 int n;12 while(cin>>n)13 {14 for(int i = 1;i<=n;++i)15 scanf("%d",a+i);16 dp[0][0] = 0;17 for(int i = 1;i<=n;++i)18 {19 dp[i][0] = dp[i-1][0]+i*a[i];20 dp[0][i] = dp[0][i-1]+i*a[n-i+1];21 }22 for(int r = 2;r<=n;++r)23 for(int i = 1;i<r;++i)24 {25 int j = r-i;26 dp[i][j] = max(dp[i-1][j]+r*a[i],dp[i][j-1]+r*a[n-j+1]);27 }28 int ans = -1;29 for(int i = 0;i<=n;++i)30 ans = max(ans,dp[i][n-i]);31 printf("%d\n",ans);32 }33 return 0;34 }
TYVJ1088
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。