题意:
一个人去杀怪,每个时刻每个位置都有一定数量的怪,一个人可以从地图的任意点出发,在某个时刻这个人可以普通攻击和放技能,普通攻击会把这个位置的怪杀掉,技能比较牛逼了,不经杀死这个位置的怪,而且相邻位置的也会杀死。
题解:
明显是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 */