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;
    }
  • 相关阅读:
    大战设计模式【13】—— 组合模式
    大战设计模式【12】—— 迭代器模式
    大战设计模式【11】—— 模板方法模式
    大战设计模式【10】—— 外观模式
    linux命令进阶
    ansible普通用户su切换
    Ansible 进阶技巧
    ansible playbook对错误的处理
    ansible示例,离线安装etcd
    (原)centos7安装和使用greenplum4.3.12(详细版)
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4830657.html
Copyright © 2011-2022 走看看