【HDU 5115】Dire Wolf

n只狼排成一行,每次击败第i只狼需要ai+bi-1+bi+1代价,击败后,相当于出列了,与i相邻两只狼成了相邻的。求击败所有狼的最小总代价。

分析

我开始一直以为是个环TAT。。

区间dp,dp[i][j]表示第i到第j只狼都被击败需要最少代价是多少。

dp[i][j]=dp[i][k-1]+dp[k+1][j]+b[i-1]+b[j+1]+a[k]

表示i到j只狼,最后击败的是第k只(i≤k≤j)。

从长度为1开始枚举,然后长度为2的...

l为长度,j=i+l-1。

只要枚举最后击败的第k只,小区间的已经算出来,那大区间也就可以求出最小代价。

因为所有狼最后都要击败,可以把a[i]一开始就累加起来。

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define N 205

using namespace std;

int b[N];
ll dp[N][N];
int main()
{
    int test;
    scanf("%d",&test);
    for(int t=1; t<=test; t++)
    {
        int n;
        scanf("%d",&n);
        int a,s=0;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a);
            s+=a;
        }
        for(int i=1; i<=n; i++) scanf("%d",&b[i]);
        memset(dp,0,sizeof dp);
        for(int l=1; l<=n; l++)
            for(int i=1; i<=n-l+1; i++)
            {
                int j=i+l-1;
                dp[i][j]=1e10;
                for(int k=i; k<=j; k++)
                    dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+b[i-1]+b[j+1]);
            }
        dp[1][n]+=s;
        printf("Case #%d: %lld\n",t,dp[1][n]);
    }
    return 0;
}

 

posted @ 2016-03-01 10:31  水郁  阅读(404)  评论(0编辑  收藏  举报
……