Treats for the Cowsios
先搬中文spa
Descriptions:.net
給你n個數字v(1),v(2),...,v(n-1),v(n),每次你能夠取出最左端的數字或者取出最右端的數字,一共取n次取完。假設你第i次取的數字是x,你能夠得到i*x的價值。你須要規劃取數順序,使得到的總價值之和最大。code
Inputblog
第一行一個數字n(1<=n<=2000)。ip
下面n行每行一個數字v(i)。(1<=v(i)<=1000)ci
Outputget
輸出一個數字,表示最大總價值和。string
Sample Inputit
5
1
3
1
5
2
Sample Output
43
Hint
按照這種下標順序取數: 1, 5, 2, 3, 4
取出的數按順序爲:1, 2, 3, 1, 5
最大總價值和:1x1 + 2x2 + 3x3 + 4x1 + 5x5 = 43.
題目連接:
https://vjudge.net/problem/POJ-3186
區間dp
dp[i][j] 表明從i取到j的最大總數
dp[i][j] = max(dp[i+1][j]+a[i]*(n+i-j) , dp[i][j-1]+a[j]*(n+i-j)) 即取右邊的數 取左邊的數 比較哪一個大
AC代碼
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define Mod 1000000007 #define eps 1e-6 #define ll long long #define INF 0x3f3f3f3f #define MEM(x, y) memset(x, y, sizeof(x)) #define Maxn 2000+10 using namespace std; int n; int dp[Maxn][Maxn],a[Maxn]; int main() { MEM(dp,0); MEM(a,0); cin>>n; for(int i=0;i<n;i++) cin>>a[i]; for(int len=0;len<n;len++)//區間長度len { for(int i=0;i+len<n;i++)//固定區間左邊起點 { int l=i,r=i+len;//區間左、右點 //取右邊的數 取左邊的數 比較哪一個大 dp[l][r]=max(dp[l+1][r]+a[l]*(n+l-r),dp[l][r-1]+a[r]*(n+l-r)); } } cout<<dp[0][n-1]<<endl; return 0; }
給你n個數字v(1),v(2),...,v(n-1),v(n),每次你能夠取出最左端的數字或者取出最右端的數字,一共取n次取完。假設你第i次取的數字是x,你能夠得到i*x的價值。你須要規劃取數順序,使得到的總價值之和最大。Input第一行一個數字n(1<=n<=2000)。
下面n行每行一個數字v(i)。(1<=v(i)<=1000)Output輸出一個數字,表示最大總價值和。Sample Input
5 1 3 1 5 2
Sample Output
43
Hint按照這種下標順序取數: 1, 5, 2, 3, 4取出的數按順序爲:1, 2, 3, 1, 5最大總價值和:1x1 + 2x2 + 3x3 + 4x1 + 5x5 = 43.