传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5115
题意:有一些狼,从左到右排列,每只狼有一个伤害A,还有一个伤害B。杀死一只狼的时候,会受到这只狼的伤害A和这只狼两边的狼的伤害B的和。若两只狼之间的狼都被杀了,这两只狼也算相邻。求杀掉一排狼的最小代价。
思路:区间DP,设f[i][j]为消灭i到j只狼的代价,枚举k作为最后一只被杀死的狼,此时会受到a[k]和b[i-1] b[j+1]的伤害 取最小的即可
转移方程:dp[i][j]=
题意:有一些狼,从左到右排列,每只狼有一个伤害A,还有一个伤害B。杀死一只狼的时候,会受到这只狼的伤害A和这只狼两边的狼的伤害B的和。若两只狼之间的狼都被杀了,这两只狼也算相邻。求杀掉一排狼的最小代价。
思路:区间DP,设f[i][j]为消灭i到j只狼的代价,枚举k作为最后一只被杀死的狼,此时会受到a[k]和b[i-1] b[j+1]的伤害 取最小的即可
转移方程:dp[i][j]=
Min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1])
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int a[205],b[205];
long long dp[205][205];
int main()
{int T,n,ca=1;scanf("%d",&T);while(T--){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]);a[0]=b[0]=a[n+1]=b[n+1]=0;/*for(int i=0;i<=n;i++){for(int j=i;j<=n;j++)dp[i][j]=inf;}*/memset(dp,0x7F,sizeof(dp));for(int l=0;l<n;l++){for(int i=1;i<=n-l;i++){int j=i+l;for(int k=i;k<=j;k++){long long L,R;if(k-1<i) L=0;else L=dp[i][k-1];if(k+1>j) R=0;else R=dp[k+1][j];dp[i][j]=min(dp[i][j],L+R+a[k]+b[i-1]+b[j+1]);// dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]);}}}printf("Case #%d: %lld\n",ca++,dp[1][n]);}return 0;
}