[区间dp] Dire Wolf HDU - 5115
题目大意:有n只狼要被消灭,杀第i只狼,猎人会受到(i-1)和(i+1)号狼的额外攻击和i号狼的正面攻击,如果两侧不存在的狼,那么不会受到额外攻击,问杀死所有狼后,猎人收到的最低伤害是多少。
分析:区间dp,狼被杀的顺序不一样,收到的伤害也就不同,因为我们要在区间内枚举最后一条被杀的狼,采取递推的形式,由小区间推向大区间。
dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+num1[k]+num2[i-1]+num2[j+1]);
初始化的时候需要注意下。
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
#define MAX 0x3f3f3f3f
#define MIN -1
#define ll long long
using namespace std;
int dp[210][210];
int main()
{
int t;
scanf("%d",&t);
int cnt=0;
while(t--)
{
int n,num1[210],num2[210];
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num1[i]);
for(int i=1;i<=n;i++)
scanf("%d",&num2[i]);
num2[0]=0;
num2[n+1]=0;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
dp[i][j]=MAX;
for(int i=0;i<=n;i++)
{
dp[0][i]=0;
dp[i][n+1]=0;
}
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]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+num1[k]+num2[i-1]+num2[j+1]);
}
}
}
printf("Case #%d: %d\n",++cnt,dp[1][n]);
}
return 0;
}