HDU 5115 Dire Wolf

来源:互联网 发布:淘宝86小铺是正品吗 编辑:程序博客网 时间:2024/05/05 12:14

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5115


题意:有一排狼,每只狼有一个基础攻击力ai,还有一个extra攻击力bi。消灭一只狼的消耗为当前狼的ai加上它左右狼的bi,中间的狼被消灭后,左右两边会自动合并。求消灭所有狼的最小消耗。


思路:区间dp,用dp[]i[]j表示消灭区间[i,j]内的狼的最小消耗。既然要消灭一个区间内的,就得有先后顺序,我们就最后一只消灭的狼来分类讨论,最后消灭i,那么dp[i][j] = min( dp[i][j] , dp[]i+1[j] + b[i-1] + b[j+1] + a[i] ),最后消灭j同理,还有就是最后消灭中间的k( i < k < j ),dp[i][j] = min( dp[i][j] , dp[i][k-1] + dp[k+1][j] + b[i-1] + b[j+1] + a[k] )。发现答案中一定会有a[i],且每个只加一次,所以可以只考虑bi。


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod %100000007const int maxn = 202;int a[maxn],b[maxn];LL dp[maxn][maxn];int T,n;LL ans = 0;void init(){    scanf("%d",&n);    rep(i,1,n) scanf("%d",&a[i]);    rep(i,1,n) scanf("%d",&b[i]);    b[0] = b[n+1] = 0;    ans = 0;    rep(i,1,n) ans+=a[i];}LL solve(){    Clean(dp,0x3f);    rep(i,1,n) dp[i][i] = b[i-1] + b[i+1];    rep( len , 2 , n )    {        rep( i , 1 , n - len + 1 )        {            int j = i + len - 1;            rep( k , i , j )            {                if ( k == i )                    dp[i][j] = min( dp[i][j] , dp[i+1][j] + b[i-1] + b[j+1] );                else if ( k == j )                    dp[i][j] = min( dp[i][j] , dp[i][j-1] + b[i-1] + b[j+1] );                else dp[i][j] = min( dp[i][j] , dp[i][k-1] + dp[k+1][j] + b[i-1] + b[j+1] );            }        }    }    return ans + dp[1][n];}int main(){    cin>>T;    rep(kase,1,T)    {        init();        printf("Case #%d: %I64d\n",kase,solve());    }    return 0;}


0 0
原创粉丝点击