zoukankan      html  css  js  c++  java
  • Codeforces Beta Round #6 (Div. 2 Only) D. Lizards and Basements 2 dp

    题目链接:

    http://codeforces.com/problemset/problem/6/D

    D. Lizards and Basements 2

    time limit per test2 seconds
    memory limit per test64 megabytes
    #### 问题描述 > This is simplified version of the problem used on the original contest. The original problem seems to have too difiicult solution. The constraints for input data have been reduced. > > Polycarp likes to play computer role-playing game «Lizards and Basements». At the moment he is playing it as a magician. At one of the last levels he has to fight the line of archers. The only spell with which he can damage them is a fire ball. If Polycarp hits the i-th archer with his fire ball (they are numbered from left to right), the archer loses a health points. At the same time the spell damages the archers adjacent to the i-th (if any) — they lose b (1 ≤ b < a ≤ 10) health points each. > > As the extreme archers (i.e. archers numbered 1 and n) are very far, the fire ball cannot reach them. Polycarp can hit any other archer with his fire ball. > > The amount of health points for each archer is known. An archer will be killed when this amount is less than 0. What is the minimum amount of spells Polycarp can use to kill all the enemies? > > Polycarp can throw his fire ball into an archer if the latter is already killed.

    输入

    The first line of the input contains three integers n, a, b (3 ≤ n ≤ 10; 1 ≤ b < a ≤ 10). The second line contains a sequence of n integers — h1, h2, ..., hn (1 ≤ hi ≤ 15), where hi is the amount of health points the i-th archer has.

    输出

    In the first line print t — the required minimum amount of fire balls.

    In the second line print t numbers — indexes of the archers that Polycarp should hit to kill all the archers in t shots. All these numbers should be between 2 and n - 1. Separate numbers with spaces. If there are several solutions, output any of them. Print numbers in any order.

    样例输入

    3 2 1
    2 2 2

    样例输出

    3
    2 2 2

    题意

    现在有n个弓箭手从1到n排成一排,每个人有hi的血量,你只能用火球术去杀死他们,如果你对第i个人使用火球术,将对他造成a点伤害,并且对i-1,i+1造成b点的火焰伤害,你不能直接打第1个和第n个人,问至少需要使用多少次火球术能杀死所有的弓箭手。

    题解

    首先想到把每人的血量作为状态,这样状态是15^10,QAQ。
    正解:dp[i][j][k][l]代表,你现在打算打第i个人,且第i-1个人的血量为j,第i个人的血量为k,第i+1个人的血量为l。
    dp[1][h[0]][h[1]][h[2]]=0.

    代码

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=10000000000000000LL;
    const double eps=1e-9;
    
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    int dp[15][20][20][20];
    int v[15];
    int n,a,b;
    
    struct Node{
        int i,j,k,l;
        bool operator == (const Node& tmp){
            return i==tmp.i&&j==tmp.j&&k==tmp.k&&l==tmp.l;
        }
        Node(int i,int j,int k,int l):i(i),j(j),k(k),l(l){}
        Node(){}
    }pre[15][20][20][20];
    
    int main() {
        scf("%d%d%d",&n,&a,&b);
        for(int i=0;i<n;i++){
            scf("%d",&v[i]);
            v[i]++;
        }
    
        clr(dp,0x3f);
        int INF=dp[0][0][0][0];
        dp[1][v[0]][v[1]][v[2]]=0;
    
        for(int i=1;i<n-1;i++){
            for(int j=v[i-1];j>=0;j--){
                for(int k=v[i];k>=0;k--){
                    for(int l=v[i+1];l>=0;l--){
                        if(dp[i][j][k][l]>=INF) continue;
    
                        if(j==0&&dp[i+1][k][l][v[i+2]]>dp[i][j][k][l]){
                            dp[i+1][k][l][v[i+2]]=dp[i][j][k][l];
                            pre[i+1][k][l][v[i+2]]=pre[i][j][k][l];
                        }
    
                        int nj=max(0,j-b);
                        int nk=max(0,k-a);
                        int nl=max(0,l-b);
    
                        if(dp[i][nj][nk][nl]>dp[i][j][k][l]+1){
                            dp[i][nj][nk][nl]=dp[i][j][k][l]+1;
                            pre[i][nj][nk][nl]=Node(i,j,k,l);
                        }
    
                        if(nj==0&&dp[i+1][nk][nl][v[i+2]]>dp[i][j][k][l]+1){
                            dp[i+1][nk][nl][v[i+2]]=dp[i][j][k][l]+1;
                            pre[i+1][nk][nl][v[i+2]]=Node(i,j,k,l);
                        }
    
                    }
                }
            }
        }
    
        prf("%d
    ",dp[n-2][0][0][0]);
    
        Node tmp=pre[n-2][0][0][0];
    
        while(1){
            prf("%d ",tmp.i+1);
            if(tmp==Node(1,v[0],v[1],v[2])) break;
            tmp=pre[tmp.i][tmp.j][tmp.k][tmp.l];
        }
    
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    欢迎加入本人建的QQ群,讨论技术,生活及每天都有招聘信息
    ThreadPool(线程池) in .Net
    Android和Unity混合开发——解决方案
    HoloLens的显示分辨率有多少?
    ARGB_8888
    这几天用高通VUFORIA的体会
    利用WMI检测电脑硬件信息,没办法显示cpu的信息
    高版本teamview的成为被控制端时,会一直出现“正在初始化显示参数”
    Windows Server 2012 R2搭建IIS服务器
    如何设置Win7不待机 Win7进入待机状态会断网的解决方法
  • 原文地址:https://www.cnblogs.com/fenice/p/6017534.html
Copyright © 2011-2022 走看看