HDU 5115--Dire Wolf

来源:互联网 发布:sql insert 已经存在 编辑:程序博客网 时间:2024/04/30 06:59

题目描述:略

题目分析:
关键字:区间DP

现在的决策就是打哪只狼,但如果按照一般的思路去决策当前打哪只狼问题就会变得异常困难,因为通过这只被杀的狼将大区间分成了两个小区间后,区间之间会互相影响,无法满足最优子结构。
那换个角度来看:
先设想一下问题的终态,当我们不停地打狼,狼的数量不停地减少,最后就会只剩下一只狼,发现从始至终由这只狼分成的两个区间之间不会有任何影响,都只作用在中间这只狼身上,所以不妨枚举最后剩下哪只狼。
F[i,j]表示打死这个区间所有狼所受的最小伤害
转移方程:F[i,j]=F[i,k-1]+F[k+1,R]+B[L-1]+B[R+1]+A[i];//A是狼的主动伤害,B是辅助伤害。

代码如下:(可以转循环,不加赘述)

#include<bits/stdc++.h>using namespace std;const int maxn=205;int T,INF;int A[maxn],B[maxn],dp[maxn][maxn];template<class T>inline void Rd(T &res){    int f=1;char c;res=0;    while(c=getchar(),c<48)if(c=='-')f=-1;    do res=(res<<1)+(res<<3)+(c^48);    while(c=getchar(),c>47);res*=f;}template<class T>inline void chkmin(T &a,T b){if(a>b) a=b;}template<class T>inline void chkmax(T &a,T b){if(a<b) a=b;}int DFS(int L,int R){    if(L>R) return 0;    if(dp[L][R]!=INF) return dp[L][R];    int &Res=dp[L][R];    //枚举i作为最后一只被杀的狼     for(int i=L;i<=R;i++) chkmin(Res,B[L-1]+B[R+1]+A[i]+DFS(L,i-1)+DFS(i+1,R));    return dp[L][R]=Res;}int main(){    Rd(T);    int cnt=T;    while(T--){        int n;        Rd(n);        for(int i=1;i<=n;i++) Rd(A[i]);        for(int i=1;i<=n;i++) Rd(B[i]);        memset(dp,0x3f,sizeof(dp));        INF=dp[0][0];        printf("Case #%d: %d\n",cnt-T,DFS(1,n));    }    return 0;}