https://ac.nowcoder.com/acm/problem/210807
刷野
区间dp:定义状态dp[i][j]表示消灭i到j怪物得最小值。第一维枚举区间长度
第二维枚举区间左端点,有了长度相应得右端点也出现,第三位枚举最后消灭哪只怪兽。
状态转移为:dp[i][j] = max(dp[i][j] , dp[i][m-1] + dp[m+1][j] + a[m] + b[i-1] + b[j+1])
注意边界得处理和初始化
#include <bits/stdc++.h> typedef long long ll ; #define int ll using namespace std ; typedef pair<int,int> pii; int quickpow(int a,int b,int mo){int s;for(s=1;b;b>>= 1,a=a*a%mo)if(b&1)s=s*a%mo;return s;} #define INF 0x3f3f3f3f const double PI = acos(-1.0); const int maxn = 5e2+9; const int N = 1e4+9; const int mod = 9901; int dp[maxn][maxn]; int a[maxn]; int b[maxn]; void Solve(){ int n ; cin >> n ; for(int i = 1 ; i <= n ; i++){ cin >> a[i]; } for(int i = 1 ; i <= n ; i++){ cin >> b[i]; } a[0] = a[n+1] = b[0] = b[n+1] = 0 ; for(int i = 1 ; i <= 500 ; i++){ for(int j = 1 ; j <= 500 ; j++){ if(j < i) dp[i][j] = 0 ; else dp[i][j] = INF; } } for(int i = 1 ; i <= n ; i++){ dp[i][i] = a[i] + b[i-1] + b[i+1]; } for(int len = 2 ; len <= n ; len++){ for(int i = 1 ; i + len - 1 <= n ; i++){ int j = i + len - 1; for(int m = i ; m <= j ; m++){ dp[i][j] = min(dp[i][j] , dp[i][m-1] + dp[m+1][j] + a[m] + b[i-1] + b[j+1]); } } } cout << dp[1][n] << endl; } //9043 signed main(){ #ifdef ONLINE_JUDGE #else freopen("D:\\c++\\in.txt", "r", stdin); //freopen("D:\\c++\\out.txt", "w", stdout); #endif Solve(); }