题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5115;
题目大意:总共有N只狼排成一排,每只狼都有一个基础攻击力ai,以及被击杀后可给别的狼提供的攻击力bi(一只狼被攻击的话,它相邻的狼会为它提供额外的攻击力bi),你击杀一只狼都会减少与这只狼攻击力加上相邻的狼提供的额外的攻击力的和的生命值,问如果要将全部狼都击杀,你最少需要减少多少生命值。
题目思路:令dp[i][j]表示击杀第i只到第j只狼所需要减少的生命值,那么最后的结果就是dp[1][n];
我们可以令k(i<=k<=j)为区间[i,j]中最后一只被击杀的狼,那么将整个区间[i,j]的狼击杀所需要减少的生命值就为
ck = dp[i][k-1]+dp[k+1][j] + a[k] + b[i-1] + b[j + 1];
那么dp[i][j] = min(ck),(k = i,i+1,i+2,...,j).
具体实现看代码。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int>pii;
const int MX = 200+7;
const int INF = 0x3f3f3f3f;
int n;
int a[MX],b[MX];
LL dp[MX][MX];
int main(){
//freopen("in.txt","r",stdin);
int T;scanf("%d",&T);
for(int cas = 1;cas <= T;cas++){
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%d",&a[i]);
}
for(int j = 1;j <= n;j++) scanf("%d",&b[j]);
for(int i = 1;i <= n;i++){
for(int j = i;j <= n;j++)
dp[i][j] = INF;
}
for(int l = 0;l <= n;l++){
for(int i = 1;i + l <= n;i++){
int j = i + l;
for(int k = i;k <= j;k++){
dp[i][j] = min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]);
}
}
}
/*for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++)
cout<< i << " " << j << " " << dp[i][j] << endl;
}*/
printf("Case #%d: %d\n",cas,dp[1][n]);
}
return 0;
}