• 51nod 1489 蜥蜴和地下室(dp)


    传送门

    题意

    分析

    dp[12][20][20][20]; // dp[a][b][c][d]第a个弓箭手面临第a-1、a、a+1个弓箭手的生命值分别为b、c、d的状态
    转移巧妙,需注意

    trick

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int inf = 0x3f3f3f3f;
    
    #define A(p) (p-a>0)?p-a:0
    #define B(p) (p-b>0)?p-b:0
    #define F(i,a,b) for(int i=a;i<=b;++i)
    
    int dp[12][20][20][20];
    int life[12];
    
    int main()
    {
        int n,a,b;
        scanf("%d %d %d",&n,&a,&b);
        int cost1,costn;
        memset(dp,0x3f,sizeof(dp));
        F(i,0,n-1)
        {
            scanf("%d",life+i);
            life[i]++;
        }
        cost1=(life[0]%b==0)?life[0]/b:life[0]/b+1;
        life[0]=0;
        life[1]=(life[1]-cost1*a>0)?life[1]-cost1*a:0;
        life[2]=(life[2]-cost1*b>0)?life[2]-cost1*b:0;
        costn=(life[n-1]%b==0)?life[n-1]/b:life[n-1]/b+1;
        life[n-1]=0;
        life[n-2]=(life[n-2]-costn*a>0)?life[n-2]-costn*a:0;
        life[n-3]=(life[n-3]-costn*b>0)?life[n-3]-costn*b:0;
        dp[1][0][life[1]][life[2]]=0;
        for(int k=1;k<n-1;++k)
            for(int i=16;i>=0;--i)
                for(int j=16;j>=0;--j)
                    for(int t=16;t>=0;--t) if(dp[k][i][j][t]!=inf)
        {
            for(int u=i,v=j,w=t;(u||v||w);)
            {
                dp[k][B(u)][A(v)][B(w)]=min(dp[k][u][v][w]+1,dp[k][B(u)][A(v)][B(w)]);
                u=B(u),v=A(v),w=B(w);
            }
            if(i==0)  dp[k + 1][j][t][life[k + 2]] = min(dp[k + 1][j][t][life[k + 2]], dp[k][i][j][t]);
        }
        printf("%d
    ",dp[n-1][0][0][0]+cost1+costn);
    }
    
  • 相关阅读:
    C
    B
    A
    poj1222
    请求转发和重定向
    中文乱码
    Servlet 第一天
    Oracle 锁
    Oracle 包的学习
    初学Linux
  • 原文地址:https://www.cnblogs.com/chendl111/p/6809081.html
Copyright © 2020-2023  润新知