UVAlive 10154:Dire Wolf 区间DP
Dire Wolf
题目链接:
题意:
有一排的狼,每只狼有一个基础攻击力a[i],和一个加成值b[i](可以给相邻的两只狼加b[i]点攻击力,这只狼死后就不加了),你每杀一只狼需要花费能量值(狼的当前攻击力),你杀了这只狼周围的狼会自动往中间聚集(即不会有空隙),求杀完n只狼所需要的最小花费。
题解:
设dp[i][j]为区间杀完区间[i,j]内的狼所需的最小花费,只要在区间[i,j]内找到一个点k使得dp[i,k-1]+dp[k+1,j]+b[i-1]+b[j+1]最小即可。
代码
#include<stdio.h>
#include<string.h>
const long long inf=100000000000000;
long long b[202],dp[202][202];
long long mmin(long long x,long long y)
{
return x<y?x:y;
}
void clean(int n)
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;++i)
for(int j=i;j<=n;++j)
dp[i][j]=inf;
}
void solve()
{
int T,n,w=0;
long long res,x;
scanf("%d",&T);
while(T--)
{
res=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%lld",&x),res+=x;
for(int j=1;j<=n;++j)
scanf("%lld",&b[j]);
b[0]=b[n+1]=0;
clean(n);
for(int len=0;len<=n;++len)
{
for(int i=1;i+len<=n;++i)
{
int j=i+len;
for(int k=i;k<=j;++k)
dp[i][j]=mmin(dp[i][j],dp[i][k-1]+dp[k+1][j]+b[i-1]+b[j+1]);
}
}
printf("Case #%d: %lld\n",++w,dp[1][n]+res);
}
}
int main()
{
solve();
return 0;
}