zoukankan      html  css  js  c++  java
  • HDU 5115 Dire Wolf(区间dp)

    题意:给定n个狼的战斗力,并且每个狼的战斗力还需要加上相邻的两个狼的额外的攻击力。当把这个狼杀死之后,它的额外的战斗力就不会给其它相邻的狼加了。每杀死一个狼,它就受到和狼攻击一样大的伤害。求杀死所有的狼最小受的伤害。

    思路:区间dp,dp[i][j]表示从i到j最小的伤害,考虑[i, j]当中的第k个,假设k最后杀死,那么它受的伤害就是a[k] + b[i - 1] + b[j + 1],这里的a为狼的攻击力。b为额外攻击力。

    不过在端点的时候要特殊判断。

    /*************************************************************************
        > File Name:            4.cpp
        > Author:               Howe_Young
        > Mail:                 1013410795@qq.com
        > Created Time:         2015年09月22日 星期二 19时33分08秒
     ************************************************************************/
    
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 221;
    const int inf = 0x3f3f3f3f;
    int a[maxn], b[maxn];
    int dp[maxn][maxn];
    int T, n;
    void init()
    {
        for (int i = 1; i <= n; i++)
            dp[i][i] = a[i] + b[i - 1] + b[i + 1];
        for (int len = 1; len <= n; len++)//枚举区间的长度
        {
            for (int i = 1; i + len <= n; i++)//枚举起点
            {
                int j = i + len;//起点加上区间长度就是终点
                dp[i][j] = inf;//初始化
                for (int k = i; k <= j; k++)//[i, j]区间最后取k的时候
                {
                    if (k == i)//当[i,j]这个区间中i最后取的时候
                    {
                        dp[i][j] = min(dp[i][j], dp[k + 1][j] + a[k] + b[i - 1] + b[j + 1]);
                    }
                    else if (k == j)
                    {
                        dp[i][j] = min(dp[i][j], dp[i][k - 1] + a[k] + b[i - 1] + b[j + 1]);
                    }
                    else
                        dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k + 1][j] + a[k] + b[i - 1] + b[j + 1]);
                }
            }
        }
    
    }
    int main()
    {
        int kase = 0;
        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]);
            b[0] = 0;
            b[n + 1] = 0;
            init();
            printf("Case #%d: %d
    ", ++kase, dp[1][n]);
        }
        return 0;
    }
  • 相关阅读:
    Java 抽象类
    Java 多态
    Java 重写与重载
    Java继承
    声卡驱动
    Sublime Text 3快捷键
    近年来世界各地ICO的花式骗局盘点
    区块链未能大爆发的影响因素有哪些?
    BCH分叉是一次站队博弈
    一文读懂百倍币的诞生背景
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4830657.html
Copyright © 2011-2022 走看看