HDU - 5115 经典区间dp

版权声明:转载请注明出处 https://blog.csdn.net/jay__bryant/article/details/82427082

题意:给定n个狼的攻击值ai和附加攻击值bi,每杀死一匹狼i,受到的伤害等于i的攻击值和与i相邻的狼的附加攻击值。求杀死所有的狼受到的伤害的最小值。

dp[i][j]:杀死区间i~j的狼受到伤害的最小值。
初始化:
a[0]=a[n+1]=b[0]=b[n+1]=0;
for(int i = 1; i <= n; ++i)
dp[i][i] = a[i]+b[i-1]+b[i+1];
状态转移
dp[l][r] = min(dp[l][r], dp[l][k-1]+dp[k+1][r]+a[k]+b[l-1]+b[r+1]);

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 210;
int a[N], b[N];
int dp[N][N];
int n;

int main()
{
    int t;
    scanf("%d", &t);
    for(int cas = 1; cas <= t; ++cas)
    {
        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;
        for(int i = 1; i <= n; ++i)
            dp[i][i] = a[i]+b[i-1]+b[i+1];
        for(int len = 2; len <= n; ++len)
            for(int l = 1; l+len-1<=n; ++l)
            {
                int r = l+len-1;
                dp[l][r] = INF;//区间dp初始化位置
                for(int k = l; k <= r; ++k)
                    dp[l][r] = min(dp[l][r], dp[l][k-1]+dp[k+1][r]+a[k]+b[l-1]+b[r+1]);
            }
        printf("Case #%d: %d\n", cas, dp[1][n]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jay__bryant/article/details/82427082
今日推荐