ACdream P1072 Kill the monster

Kill The Monster

Time Limit: 4000/2000MS (Java/Others)Memory Limit: 65536/32768KB (Java/Others)

Problem Description

Xxx正在玩一款遊戲,遊戲地圖上有N個點,這些點之間有M條邊。遊戲系統會在一定時間在某點刷新出一定量的怪,系統刷新出來的怪只會存在1秒,下一秒就會消失。如果那個時間xxx正好在那個點,那麼xxx可以秒殺這個點上的所有怪。另外,xxx還有B次放大招的機會,每次放大招可以秒殺掉當前所在點及與其相鄰點上的所有怪。大招有5秒的冷卻時間,也就是說每次放大後要經過5秒鐘才能再次放大。Xxx想知道T時間內他最多可以殺掉多少隻怪。Xxx可以從任意點開始。系統時間從1開始。

Input

輸入的第一行包含一個整數CT(CT<=50), 表示一共有CT組測試數據。

對於每組測試數據,第一行包含5個整數N、M、T、K、B(1 <= N, T <= 50, 0<=M<= (N-1)*N/2, 0<=K<=10000, 0<=B<=5)。N、M、T意義如上所述,K表示有K個系統刷新。

接下來是M行,每行有3個整數u、v、t(1<=u, v<=N, u!=v, 1<=t<=10)表示從u走到v或者從v走到u需要花費t的時間。數據保證沒有重邊。

然後是K行,每行有3個整數t、p、c(1<=t<=50, 1<=p<=N, 1<=c<=100)表示t時間 在p點刷新出c個怪。

Output

對於每組測試數據,輸出在T時間內xxx最多可以殺掉多少隻怪。

Sample Input

2
5 4 3 9 2
1 2 1
2 3 2
2 4 1
2 5 1
1 1 2
2 1 1
2 2 2
2 3 3
2 4 4
2 5 5
3 3 5
3 4 1
3 5 1
5 4 6 8 2
1 2 1
2 3 2
2 4 1
2 5 1
1 1 1
1 2 1
4 3 1
6 1 1
6 2 1
6 3 1
6 4 1
6 5 1

Sample Output

18
8

Hint

第一組測試數據

第1秒,xxx在點1,普通攻擊

點1走到點2

第2秒,xxx在點2,放大

點2走到點4

第3秒,xxx在點4,普通攻擊

Source

zju_xxx

Manager





一道畢竟典型的DP,維數較多的情況下各個維的範圍都不高,很像我高一參加的某界NOIP初賽的題目,根據已有的狀態更新新的狀態即可,設DP[點][時間][使用大招數][大招此時冷卻時間],下面怎麼推我想你應該知道了吧。


代碼:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack> 
#include<vector>
#include<cmath>
#define rep(i,n) for(i=1;i<=n;i++)
#define MM(a,t) memset(a,t,sizeof(a))
#define INF 1e9
typedef long long ll;
#define mod 1000000007
using namespace std;
int val[52][52],map[52][52];
int n,m,t,k,b;
int dp[62][62][12][12];
int bbv[62][62];
int calsum(int node,int ti)
{
	int i,j,res=0;
	if(bbv[node][ti]!=-1) return bbv[node][ti];
	rep(i,n)
	if(node!=i && map[node][i]!=-1)
	  res+=val[i][ti];
    
    return bbv[node][ti]=res;
}
int main()
{
	int i,j,T,bs,cd,y;

    scanf("%d",&T);
    while(T--)
    {
    	MM(val,0); MM(map,-1); MM(bbv,-1);
    	scanf("%d%d%d%d%d",&n,&m,&t,&k,&b);
    	rep(i,m)
    	{
    	  int s,e,v;
    	  scanf("%d%d%d",&s,&e,&v);
    	  map[s][e]=map[e][s]=v;
	    }
	    rep(i,n) map[i][i]=1; 
	    rep(i,k)
	    {
   		  int no,ti,v;
   		  scanf("%d%d%d",&ti,&no,&v);
   		  val[no][ti]+=v;
    	}
        MM(dp,-1);
		rep(i,n) 
		{
			dp[i][1][0][0]=val[i][1];
			dp[i][1][1][5]=val[i][1]+calsum(i,1);
		}
		int ans=0;
		rep(i,t)
		  rep(j,n)
            for(bs=0;bs<=b;bs++)
              for(cd=0;cd<=5;cd++)
              if(dp[j][i][bs][cd]!=-1)
              {
  	            ans=max(ans,dp[j][i][bs][cd]);
                rep(y,n)
                if(map[j][y]!=-1 && i+map[j][y]<=t)
                { 
                	int lt=map[j][y];
                	int bv=calsum(y,i+lt);
                	int lc=cd-map[j][y];
                	if(lc<0) lc=0;
              dp[y][i+lt][bs][lc]=max(dp[y][i+lt][bs][lc],dp[j][i][bs][cd]+val[y][i+lt]);
           	  if(lc==0)  dp[y][i+lt][bs+1][5]=max(dp[y][i+lt][bs+1][5],dp[j][i][bs][cd]+val[y][i+lt]+bv);	
                }
              }
    	
          printf("%d\n",ans);
    }
    
	
	return 0;
}


今天被鎮海中學出的智商題給虐哭了qaq。。。




發佈了41 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章