HDU-5115 Dire Wolf(区间DP)

题意:Matt面前有n匹狼排成一排,他要将这些狼全部杀死才能活下来,第i匹狼有两个数据ai,bi,分别表示它的基础攻击力和它能为相邻的狼带来的附加攻击力。其中一匹狼被杀死后,它左右的狼视为相邻,Matt将受到它的基础攻击力与它左右的狼带来的附加攻击力之和的伤害,求要活下来受到到最小伤害。(n<=200)

无论是怎样的转移,都无疑是由小区间推得大区间,现在dp[L][R]表示杀死区间[L,R]内的狼受到的最小伤害,为了转移状态需要分割区间。我们设区间[L,R]中最后一个杀死的是k号狼,那么杀死k号狼受到的伤害即为b[L-1]+b[R+1]+a[k],转移方程为dp[L][R]=min{dp[L][k-1]+dp[k+1][R]+a[k]+b[L-1]+b[R+1]}

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define FOR(i,x,y) for(int i=(x);i<=(y);i++)
#define DOR(i,x,y) for(int i=(x);i>=(y);i--)
#define memclear(a) memset(a,0,sizeof(a))
#define N 200
using namespace std;
int a[N+3],b[N+3];
int dp[N+3][N+3];

int main()
{
    int T;
    scanf("%d",&T);
    FOR(Ti,1,T)
    {
    	memclear(a);memclear(b);memclear(dp);
    	int n;
    	scanf("%d",&n);
    	FOR(i,1,n)scanf("%d",&a[i]);
    	FOR(i,1,n)scanf("%d",&b[i]);
    	FOR(l,1,n)  //枚举区间长度
		    FOR(L,1,n-l+1)  //枚举左端点
			{
			    int R=L+l-1;
			    dp[L][R]=1e9;
				FOR(k,L,R)   //k为区间[L,R]中最后杀死的狼
				    dp[L][R]=min(dp[L][R],dp[L][k-1]+dp[k+1][R]+a[k]+b[L-1]+b[R+1]);
			}
		printf("Case #%d: %d\n",Ti,dp[1][n]);
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/paulliant/article/details/80227338
今日推荐