1. 程式人生 > >HDU 5115 Dire Wolf (區間dp)

HDU 5115 Dire Wolf (區間dp)

題意:

一群狼排成一排,每隻狼有一個固定攻擊值a[i],還有附加值他左右與它相鄰的狼給它的附加值,因此它對人的攻擊總值是固定攻擊值+附加值,一個人消滅第i只狼的同時會受到它的總攻擊值的傷害,問一個人要按什麼順序消滅全部狼,能使獲得受到的攻擊值最低。

思路:

區間dp好難呀。

區間DP。

dp[i][j]表示從第i頭狼到第j頭狼全部被殺死所受到的最小傷害。a[i]表示第i頭狼的初始攻擊力,b[i]表示第i頭狼對相鄰狼的加成值。 dp[i][j]=min(dp[i][k-1]+a[k]+dp[k+1][j])+b[i-1]+b[j+1]; (i<k<j&&j>i),其中k為區間i到j中最後一隻殺死的狼。 dp[i][j]=a[i]+b[i-1]+b[j+1];  (i=j);

參考大佬程式碼:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 222;
int a[maxn];
int b[maxn];
int dp[maxn][maxn];
int main()
{
    int t;
    int cnt=1;
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        memset(a,0,sizeof a);
        memset(b,0,sizeof b);
        memset(dp,0,sizeof dp);
        int n;
        cin>>n;
        for(int i=1; i<=n; i++)
            cin>>a[i];
        for(int i=1; i<=n; i++)
            cin>>b[i];
        for(int i=1; i<=n; i++)
            dp[i][i]=a[i]+b[i-1]+b[i+1];
        for(int i=n-1; i>=1; i--)
            for(int j=i+1; j<=n; j++)
            {
                dp[i][j]=min(dp[i+1][j]+a[i]+b[i-1]+b[j+1],dp[i][j-1]+a[j]+b[i-1]+b[j+1]);
                for(int k=i+1; k<=j-1; k++)
                {
                    dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]);
                }
            }
        printf("Case #%d: %d\n",cnt++,dp[1][n]);
    }
    return 0;
}