POJ 3186Treats for the Cows(区间DP)
生活随笔
收集整理的這篇文章主要介紹了
POJ 3186Treats for the Cows(区间DP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:http://poj.org/problem?id=3186
題目大意:給出的一系列的數字,可以看成一個雙向隊列,每次只能從隊首或者隊尾出隊,第n個出隊就拿這個數乘以n,最后將和加起來,求最大和。
解題思路:有兩種寫法:
①這是我一開始想的,從外推到內,設立數組dp[i][j]表示剩下i~j時的最優解,則有狀態轉移方程:
dp[i][j]=dp[i][j]=max(dp[i-1][j]+a[i-1]*(n-(j-i+1)),dp[i][j+1]+a[j+1]*(n-(j+1-i)))
最后推到dp[i][i]就只剩下一個物品,再計算一次找最大值即可。
②網上看的,區間DP,由內推到外,有狀態轉移方程:dp[i][j]=max(dp[i+1][j]+a[i]*(n-j+i),dp[i][j-1]+a[j]*(n-j+i))
代碼①:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long LL; 5 const int N=2e3+5; 6 const int inf=1<<30; 7 int a[N]; 8 int dp[N][N];//還剩下i~j件物品時的最優解 9 10 int main(){ 11 int n; 12 while(~scanf("%d",&n)){ 13 for(int i=1;i<=n;i++) 14 scanf("%d",&a[i]); 15 16 dp[0][5]=dp[1][6]=0; 17 for(int i=1;i<=n;i++){ 18 for(int j=n;j>=i-1;j--){ 19 dp[i][j]=max(dp[i-1][j]+a[i-1]*(n-(j-i+1)),dp[i][j+1]+a[j+1]*(n-(j+1-i))); 20 } 21 } 22 int ans=0; 23 for(int i=1;i<=n;i++){ 24 ans=max(dp[i][i]+n*a[i],ans); 25 } 26 printf("%d\n",ans); 27 } 28 return 0; 29 }代碼②:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=2e3+5; 6 const int inf=1<<30; 7 int a[N]; 8 int dp[N][N]; 9 10 int main(){ 11 int n; 12 while(~scanf("%d",&n)){ 13 memset(dp,0,sizeof(dp)); 14 for(int i=1;i<=n;i++) 15 scanf("%d",&a[i]); 16 17 for(int i=n;i>=1;i--){ 18 for(int j=i;j<=n;j++){ 19 dp[i][j]=max(dp[i+1][j]+a[i]*(n-j+i),dp[i][j-1]+a[j]*(n-j+i)); 20 } 21 } 22 printf("%d\n",dp[1][n]); 23 } 24 return 0; 25 }?
轉載于:https://www.cnblogs.com/fu3638/p/7501349.html
總結
以上是生活随笔為你收集整理的POJ 3186Treats for the Cows(区间DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有1,2,3,4四个数字,能组成多少个互
- 下一篇: jquery是库还是框架?