[luoguP2858] [USACO06FEB]奶牛零食Treats for the Cows(DP)
阿新 • • 發佈:2017-05-24
turn pri class 分享 blank .org splay == pla
傳送門
f[i][j][k] 表示 左右兩段取到 i .... j 時,取 k 次的最優解
可以優化 k 其實等於 n - j + i
則 f[i][j] = max(f[i + 1][j] + a[i] * (n - j + i), f[i][j - 1] + a[j] * (n - j + i))
邊界 f[i][i] = a[i] * n
遞推順序不好求,所以選擇記憶化搜索。
——代碼
1 #include <cstdio> 2 #include <iostream> 3 4 const intView CodeMAXN = 2001; 5 int n; 6 int a[MAXN], f[MAXN][MAXN]; 7 8 inline int read() 9 { 10 int x = 0, f = 1; 11 char ch = getchar(); 12 for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1; 13 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘; 14return x * f; 15 } 16 17 inline int max(int x, int y) 18 { 19 return x > y ? x : y; 20 } 21 22 inline int dp(int x, int y) 23 { 24 if(f[x][y]) return f[x][y]; 25 if(x == y) return f[x][y] = a[x] * n; 26 else return f[x][y] = max(dp(x + 1, y) + a[x] * (n - y + x), dp(x, y - 1) + a[y] * (n - y + x)); 27 } 28 29 int main() 30 { 31 int i; 32 n = read(); 33 for(i = 1; i <= n; i++) a[i] = read(); 34 printf("%d\n", dp(1, n)); 35 return 0; 36 }
[luoguP2858] [USACO06FEB]奶牛零食Treats for the Cows(DP)