题意: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;
}