zoukankan      html  css  js  c++  java
  • 蒜头君的坐骑

    蒜头君的坐骑

    题目描述

    蒜头君有一只坐骑,人马。

    一天,蒜头君骑着他的坐骑走上了一片 n×m 的大荒野,一开始时,蒜头君在 (1,1) 点,他要前往(n,m) 点,蒜头君的人马每次可以向右或向下移动一格。然而这片荒野并不平静,除了起点和终点外每个点都有一只怪物会袭击蒜头君。

    然而蒜头君的人马强大无比,它会先对怪物造成等同于它攻击力的伤害,然后蒜头君才会受到怪物的攻击,伤害等同于怪物的攻击力。然后人马再攻击怪物,怪物再攻击蒜头君,直至怪物死去,假设每个怪物具有相同的体力。

    此外,蒜头君的人马还有一个强大无比的技能,使用该技能会使蒜头君接下来 k 次移动,每一次移动后增加等同于移动到的格子的怪物的攻击力,k 次移动后,人马攻击力恢复至初始攻击力。人马必须在当前一个技能释放完后才可以释放下一个技能,且一共可释放技能的次数有限,那么试问蒜头君从起点到终点最少受到多少点伤害。

    注意:蒜头君的体力是无限的。

    输入输出格式

    输入格式:

    第一行六个正整数 n,m,t,k,h,atk,表示地图长度、宽度、人马技能可使用次数、人马技能持续移动次数、每只怪物的体力和人马的初始攻击力。保证 n+m−1≥t×k。

    接下来 n 行,每行 m 个整数,表示每个点的怪物的攻击力。保证 (1,1) 点、(n,m) 点为 0,其他点为正整数。

    输出格式:

    输出一个整数,表示蒜头君受到的最小伤害。

    说明

    对于 30% 的测试数据,满足 1≤n,m≤10, 1≤t≤3, 1≤k≤3;

    对于 60% 的测试数据,满足 1≤n,m≤100, 1≤t≤10, 1≤k≤5;

    对于 100% 的测试数据,满足1≤n,m≤500, 1≤t≤10, 1≤k≤5, 1≤atk≤h≤100, 1≤ 怪物攻击力 ≤100。


    第一次做类似的题目,算做积累了。

    思想不难,就是整体DP,局部搜索。(据说还有一种有后效性的DP是整体DP,局部高斯消元)

    (dp[i][j][k])(i)(j)列第(k)次使用技能的最小伤害。

    当不释放技能时,直接转移:(cnt为原始攻击需要打的次数)

    dp[i+1][j][l]=min(dp[i+1][j][l],dp[i][j][l]+cnt*atk[i+1][j]);
    dp[i][j+1][l]=min(dp[i][j+1][l],dp[i][j][l]+cnt*atk[i][j+1]);
    

    搜索释放技能能到达的答案并更新dp。

    为了确保这样是对的,有这样一句话“使用该技能会使蒜头君接下来 k 次移动,每一次移动后增加等同于移动到的格子的怪物的攻击力”,也就是说,放技能是连续的。而k值的范围又小。

    整体复杂度(O(nmtk!)),基本能过


    code:

    #include <cstdio>
    #include <cstring>
    int min(int x,int y){return x<y?x:y;}
    const int N=502;
    int n,m,t,k,h,atk0;
    //长、宽、使用次数、持续移动次数、怪物体力和初始攻击力
    int dp[N][N][12],atk[N][N];
    void dfs(int i,int j,int tt,int atkk,int cntt,int mi)
    {
        if(cntt>k)
            return;
        atkk+=atk[i][j];
        mi+=atk[i][j]*(h%atkk?h/atkk:h/atkk-1);
        dp[i][j][tt]=min(dp[i][j][tt],mi);
        if(i<n)
            dfs(i+1,j,tt,atkk,cntt+1,mi);
        if(j<m)
            dfs(i,j+1,tt,atkk,cntt+1,mi);
    }
    int main()
    {
        scanf("%d%d%d%d%d%d",&n,&m,&t,&k,&h,&atk0);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&atk[i][j]);
        int cnt=h%atk0?h/atk0:h/atk0-1;
        memset(dp,0x3f,sizeof(dp));
        dp[1][1][0]=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                for(int l=0;l<=t;l++)
                {
                    dp[i+1][j][l]=min(dp[i+1][j][l],dp[i][j][l]+cnt*atk[i+1][j]);
                    dp[i][j+1][l]=min(dp[i][j+1][l],dp[i][j][l]+cnt*atk[i][j+1]);
                    if(l<t)
                    {
                        if(i<n)
                            dfs(i+1,j,l+1,atk0,1,dp[i][j][l]);
                        if(j<m)
                            dfs(i,j+1,l+1,atk0,1,dp[i][j][l]);
                    }
                }
        printf("%d
    ",dp[n][m][t]);
        return 0;
    }
    
    

    2018.6.23

  • 相关阅读:
    SilverLight学习篇——框架搭建及实例讲述(huangyezi)
    MVVMLight学习
    MVVMLight学习篇——WPF MVVMLightToolkit(李凤桐)
    MvvmLight学习篇—— Mvvm Light Toolkit for wpf/silverlight系列(子林)
    Erro:Namespace http://schemas.microsoft.com/expression/blend/2008 is not resolved.
    MEF学习篇——MEF程序设计指南(Bēniaǒ)
    Error:The tag 'Label' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk'.
    silverlight页面间常用跳转模式
    UIViewController的生命周期以及相互之间通信
    解析:如何快速掌握SQL Server的锁机制
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9218220.html
Copyright © 2011-2022 走看看