传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5115
森林狼嘛,1费11但是可以给相邻的随从加buff,hhh
现在有一列森林狼,你需要A死他们,当然你也会受到伤害每一只森林狼有自己的攻击力a[i],以及对相邻的加成b[i],当一只森林狼挂掉后两边的即成相邻
求消耗最少的血量
区间DP
设f[i][j]为i~j消耗的血量,
f[i][j]=min(f[i][k]+f[k+1][j]+a[k])+b[i-1]+b[j+1] (i<k<j)
这样只能处理区间长度>=3的情况,对于长度=1或=2的情况需要预处理出来
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>using namespace std;int T;int n;int a[205],b[205];int f[205][205];int main()
{scanf("%d",&T);for (int t=1;t<=T;t++){memset(a,0,sizeof(a));memset(b,0,sizeof(b));scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%d",&a[i]);}for (int i=1;i<=n;i++){scanf("%d",&b[i]);}for (int i=1;i<=n;i++){f[i][i]=a[i]+b[i-1]+b[i+1];}for (int l=2;l<=n;l++){for (int i=1;i+l-1<=n;i++){int j=l+i-1;f[i][j]=min(f[i+1][j]+a[i],f[i][j-1]+a[j]);for (int k=i+1;k<j;k++){f[i][j]=min(f[i][j],f[i][k-1]+f[k+1][j]+a[k]);}f[i][j]+=b[i-1]+b[j+1];}}printf("Case #%d: %d\n",t,f[1][n]);}return 0;
}