acdream 1072 Kill The Monster (dp)

题意:

一个人去杀怪,每个时刻每个位置都有一定数量的怪,一个人可以从地图的任意点出发,在某个时刻这个人可以普通攻击和放技能,普通攻击会把这个位置的怪杀掉,技能比较牛逼了,不经杀死这个位置的怪,而且相邻位置的也会杀死。

题解:

明显是dp,直接根据需要设置状态就好dp[i][u][j][co],表示时间i在地图上u位置用了j次技能并且此事技能还需co的冷却时间。于是直接根据人在地图上的行走来状态转移。题目不难,但是坑点真orz,说好的某个时间某个位置怪的数量,竟然有相同的时间和位置的输入,orz。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void cmax(int& a,int b){ if(b>a)a=b; }
void cmin(int& a,int b){ if(b<a)a=b; }
void cmax(ll& a,ll b){ if(b>a)a=b; }
void cmin(ll& a,ll b){ if(b<a)a=b; }
void add(int& a,int b,int mod){ a=(a+b)%mod; }
void add(ll& a,ll b,ll mod){ a=(a+b)%mod; }
const int oo=0x3f3f3f3f;
const ll OO=0x3f3f3f3f3f3f3f3f;
const ll MOD=1000000007;
const int maxn = 55;
const int maxm = 55*55;
int dp[maxn][maxn][6][6];
int num[maxn][maxn],num2[maxn][maxn];
struct EDGE{
    int v,w,next;
}E[maxm<<1];
int head[maxn],tol;

void Init(){
    memset(head,-1,sizeof head);
    tol=0;
}

void add_edge(int u,int v,int w){
    E[tol].v=v;
    E[tol].next=head[u];
    E[tol].w=w;
    head[u]=tol++;
}

int main(){
    //freopen("G:\\read.txt","r",stdin);
    int N,M,T,K,B,CT,c,t,p;
    scanf("%d",&CT);
    while(CT--){
        Init();
        scanf("%d %d %d %d %d",&N,&M,&T,&K,&B);
        for(int i=1;i<=N;i++)
            add_edge(i,i,1);
        for(int i=1;i<=M;i++){
            int u,v;
            scanf("%d %d %d",&u,&v,&c);
            add_edge(u,v,c);
            add_edge(v,u,c);
        }
        memset(num,0,sizeof num);
        memset(num2,0,sizeof num2);
        for(int i=1;i<=K;i++){
            scanf("%d %d %d",&t,&p,&c);
            num[t][p]+=c;
        }
        for(int i=1;i<=T;i++){
            for(int j=1;j<=N;j++){
                num2[i][j]=num[i][j];
                for(int k=head[j];k!=-1;k=E[k].next){
                    if(E[k].v==j)continue;
                    num2[i][j]+=num[i][E[k].v];
                }
            }
        }
        memset(dp,-1,sizeof dp);
        for(int u=1;u<=N;u++){
            dp[1][u][0][0]=num[1][u];
            if(B>=1)
            dp[1][u][1][5]=num2[1][u];
        }
        int ans=0;
        for(int i=1;i<=T;i++){
            for(int u=1;u<=N;u++){
                for(int j=0;j<=B;j++){
                    for(int co=0;co<=5;co++){
                        cmax(ans,dp[T][u][j][co]);
                        if(dp[i][u][j][co]==-1)continue;
                        for(int l=head[u];l!=-1;l=E[l].next){
                            int v=E[l].v,w=E[l].w;
                            if(i+w>T)continue;
                            cmax(dp[i+w][v][j][max(0,co-w)],dp[i][u][j][co]+num[i+w][v]);
                            if(co-w<=0&&j+1<=B)
                            cmax(dp[i+w][v][j+1][5],dp[i][u][j][co]+num2[i+w][v]);
                        }
                    }
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
/*
1000
2 1 1 1 0
1 2 1
1 2 1000
*/



你可能感兴趣的:(acdream 1072 Kill The Monster (dp))