HDU - 5115 Dire Wolf(区间dp)

原题链接

题意:n只狼,每只狼有自己的攻击力,同时也会受到相邻狼的加成,问杀死n只狼后受到的最少攻击。

分析:区间dp。
定义状态 dp[i][j]为第i只到第j只狼都被杀了后受到的最少攻击。
那么 dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]) (i<k<j).枚举区间,然后枚举这个区间里的任意一只狼,杀了它,此时区间内其他狼都已被杀。注意初始化。

 

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdlib>
#include<climits>
#include<ctype.h>
#include<set>
#include<map>
#define pi acos(-1.0)
#define mem(a) memset(a,0,sizeof(a))
#define mems(a,b) memset((a),(b),sizeof(a))
#define ll long long
#define ull unsigned long long
//#define LOCAL
#define ls root<<1
#define rs root<<1|1
#define Ls root<<1,l,mid
#define Rs root<<1|1,mid+1,r
using namespace std;
const int maxn=(1<<20);
const int inf=0x3f3f3f3f;
const int INF=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;

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

int main()
{
    //ios::sync_with_stdio(false);
#ifdef LOCAL
    freopen("data","r",stdin);
//    freopen("out","w",stdout);
#endif
    int t,n,m,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]=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++) printf("%d ",dp[i][i]);puts("");
        for(int j=2;j<=n;j++){
            for(int i=1;i<=n-j+1;i++){
                int k=i+j-1;
                dp[i][k]=min(dp[i][k-1]+a[k]+b[k+1]+b[i-1],dp[i+1][k]+a[i]+b[k+1]+b[i-1]);
                for(int l=i+1;l<k;l++){
                    dp[i][k]=min(dp[i][l-1]+dp[l+1][k]+a[l]+b[i-1]+b[k+1],dp[i][k]);
                }
            }
        }
        printf("Case #%d: %d\n",cas++,dp[1][n]);
    }
    return 0;
}

 

posted @ 2017-07-30 19:36  litos  阅读(220)  评论(0编辑  收藏  举报