首页 > 代码库 > HDU5115 Dire Wolf (区间DP)

HDU5115 Dire Wolf (区间DP)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5115


题意:

有n只狼,每只狼有两种属性,一种攻击力一种附加值,我们没杀一只狼,那么我们受到的伤害值为

这只狼的攻击值与它旁边的两只狼的附加值的和,求把所有狼都杀光受到的最小的伤害值。


分析:

赤裸裸的区间DP

dp[i][j]表示把区间i,j内的所有狼杀光所受到的最小的伤害。

状态转移方程为

dp[i][j]=min{dp[i][k]+dp[k+1][j]-b[k]+b[i+1],dp[i][k]+dp[k+1][j]-b[k+1]+b[j+1]}(i<=k<j)这里讨论了先杀左边的还是先杀右边的

处理的时候要注意a[0],b[0],a[n+1],b[n+1]的初值都是0.


代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int maxn = 210;

int dp[maxn][maxn];
int a[maxn],b[maxn];


int main()
{
    int n,t,cas=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]=a[n+1]=0;
        b[0]=b[n+1]=0;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            dp[i][i]=a[i]+b[i-1]+b[i+1];
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                dp[i][j]=999999999;
        for(int len = 2;len<=n;len++){
            for(int i=1;i+len-1<=n;i++){
                int j=i+len-1;
                for(int k=i;k<j;k++){
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+b[i-1]-b[k]);
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+b[j+1]-b[k+1]);
                }
            }
        }
        printf("Case #%d: %d\n",cas++,dp[1][n]);
    }
    return 0;
}


HDU5115 Dire Wolf (区间DP)