zoukankan      html  css  js  c++  java
  • BZOJ3875 [Ahoi2014]骑士游戏

    Description

     【故事背景】
    长期的宅男生活中,JYY又挖掘出了一款RPG游戏。在这个游戏中JYY会扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽。
    【问题描述】
    在这个游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻击。两种攻击方式都会消耗JYY一些体力。采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个怪兽可能 经过若干次普通攻击后变回一个或更多同样的怪兽;而采用法术攻击则可以彻底将一个怪兽杀死。当然了,一般来说,相比普通攻击,法术攻击会消耗更多的体力值 (但由于游戏系统bug,并不保证这一点)。
    游戏世界中一共有N种不同的怪兽,分别由1到N编号,现在1号怪兽入侵村庄了,JYY想知道,最少花费多少体力值才能将所有村庄中的怪兽全部杀死呢?

    Input

    第一行包含一个整数N。
    接下来N行,每行描述一个怪兽的信息;
    其中第i行包含若干个整数,前三个整数为Si,Ki和Ri,表示对于i号怪兽,普通攻击需要消耗Si的体力,法术攻击需要消耗Ki的体力,同时i号怪兽死亡后会产生Ri个新的怪兽。表示一个新出现的怪兽编号。同一编号的怪兽可以出现多个。
     

    Output

     输出一行一个整数,表示最少需要的体力值。

    Sample Input

    4
    4 27 3 2 3 2
    3 5 1 2
    1 13 2 4 2
    5 6 1 2

    Sample Output

    26

    HINT

    【样例说明】

    首先用消耗4点体力用普通攻击,然后出现的怪兽编号是2,2和3。花费10点体力用法术攻击杀死两个编号为2的怪兽。剩下3号怪兽花费1点体力进行普通攻击。此时村庄里的怪兽编号是2和4。最后花费11点体力用法术攻击将这两只怪兽彻底杀死。一共花费的体力是4+5+5+1+5+6=26。

    【数据范围】

    2<=N<=2*10^5,1<=Ri,Sigma(Ri)<=10^6,1<=Ki,Si<=5*10^14

     

     

    正解:SPFA+有后效性DP

    解题报告:

      考虑直接DP,显然有后效性,会不断影响到之前的所有结点。那么我们用SPFA维护更新操作,保证每次更新能够使所有可更新的结点被更新。

      最开始把所有结点加入队列,因为最开始都可以被更新。

      记得开long long  

     

     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #ifdef WIN32   
    14 #define OT "%I64d"
    15 #else
    16 #define OT "%lld"
    17 #endif
    18 using namespace std;
    19 typedef long long LL;
    20 const int MAXN = 200011;
    21 const int MAXM = 4000011;
    22 int n,m;
    23 LL f[MAXN],g[MAXN];//f[i]表示消灭掉i的最小花费,g[i]表示物理攻击i后并消灭产生新怪物后的开销
    24 int first[MAXN],next[MAXM],to[MAXM];
    25 int head[MAXN],ecnt,ccnt;
    26 bool vis[MAXN];
    27 queue<int>Q;
    28 struct edge{
    29     int next,to;
    30 }e[MAXM];
    31 
    32 inline int getint()
    33 {
    34        int w=0,q=0;
    35        char c=getchar();
    36        while((c<'0' || c>'9') && c!='-') c=getchar();
    37        if (c=='-')  q=1, c=getchar();
    38        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    39        return q ? -w : w;
    40 }
    41 
    42 inline LL getlong()
    43 {
    44        LL w=0,q=0;
    45        char c=getchar();
    46        while((c<'0' || c>'9') && c!='-') c=getchar();
    47        if (c=='-')  q=1, c=getchar();
    48        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    49        return q ? -w : w;
    50 }
    51 
    52 inline void link(int x,int y){ next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; }
    53 
    54 inline void link2(int x,int y){  e[++ccnt].next=head[x]; head[x]=ccnt; e[ccnt].to=y; }
    55 
    56 inline void SPFA(){
    57     while(!Q.empty()) {
    58     int u=Q.front(); Q.pop(); vis[u]=0;
    59     if(f[u]<=g[u]) continue;//已经更优
    60     for(int i=head[u];i;i=e[i].next) {
    61         if(!vis[e[i].to]) vis[e[i].to]=1,Q.push(e[i].to);
    62         g[e[i].to]-=f[u];
    63         g[e[i].to]+=g[u];
    64     }
    65     f[u]=g[u];//存在更优的策略
    66     }
    67 }
    68 
    69 inline void work(){
    70     n=getint(); int x;
    71     for(int i=1;i<=n;i++) { 
    72     g[i]=getlong();    f[i]=getlong();//初值定为物理攻击和法力攻击
    73     m=getint(); Q.push(i); vis[i]=1;
    74     for(int j=1;j<=m;j++) x=getint(),link(i,x),link2(x,i);
    75     }
    76     for(int i=1;i<=n;i++) for(int j=first[i];j;j=next[j]) g[i]+=f[to[j]];
    77     SPFA();
    78     printf("%lld",f[1]);
    79 }
    80 
    81 int main()
    82 {
    83   work();
    84   return 0;
    85 }
  • 相关阅读:
    岗位要求与人才匹配
    http://blog.csdn.net/wujunokay/article/details/44783383
    好单位与坏单位
    工作那些事(三十四)杂记
    工作那些事(三十三)面试官的感想和建议
    工作那些事(三十二)由孙悟空的两个故事谈个人与团队
    工作那些事(三十一)如何带好一个项目团队
    工作那些事(三十)如何提升个人能力
    工作那些事(二十九)团队建设和人才招聘
    工作那些事(二十八)项目管理模式:项目型、职能型、矩阵型
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5760926.html
Copyright © 2011-2022 走看看