[luogu 1270] “訪問”美術館 (樹形dp)
阿新 • • 發佈:2018-07-20
2個 結果 pac 轉移 using lld space p12 多少
一個展室最多有20幅畫。通過每個走廊的時間不超過20s。藝術館最多有100個展室。警察趕到的時間在10min以內。
傳送門
Description
經過數月的精心準備,Peer Brelstet,一個出了名的盜畫者,準備開始他的下一個行動。藝術館的結構,每條走廊要麽分叉為兩條走廊,要麽通向一個展覽室。Peer知道每個展室裏藏畫的數量,並且他精確測量了通過每條走廊的時間。由於經驗老到,他拿下一幅畫需要5秒的時間。你的任務是編一個程序,計算在警察趕來之前,他最多能偷到多少幅畫。
Input
第1行是警察趕到的時間,以s為單位。第2行描述了藝術館的結構,是一串非負整數,成對地出現:每一對的第一個數是走過一條走廊的時間,第2個數是它末端的藏畫數量;如果第2個數是0,那麽說明這條走廊分叉為兩條另外的走廊。數據按照深度優先的次序給出,請看樣例。
Output
輸出偷到的畫的數量
Sample Input
60
7 0 8 0 3 1 14 2 10 0 12 4 6 2
Sample Output
2
Solution
dfs時記錄到這個節點最多剩多長時間
然後枚舉這個節點和它子節點(如果有的話)的消耗時間直接轉移即可
PS:本來想著做幾道做幾道比較水的樹形dp結果。。WA三次QAQ,查了半天代碼最後絕望去看題解發現由於要“在警察趕來之前”所以輸入的時間要-1。。,好吧是我太蠢了QAQ
Code
//By Menteur_Hxy #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define int long long #define ls nd[x][0] #define rs nd[x][1] #define F(i,a,b) for(register int i=(a);i<=(b);i++) using namespace std; int read() { int x=0,f=1; char c=getchar(); while(!isdigit(c)) {if(c=='-') f=-f; c=getchar();} while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar(); return x*f; } const int N=110; int T,tot=1; int nd[N<<2][2],ti[N<<2],pi[N<<2],dp[N<<2][6010]; void build(int x) { ti[x]=read(),pi[x]=read(); if(!pi[x]) ls=++tot,build(tot),rs=++tot,build(tot); } void dfs(int x,int t) { if(pi[x]) F(i,ti[x]*2+1,min(t,ti[x]*2+5*pi[x])) dp[x][i]=(i-ti[x]*2)/5; else if(t>ti[x]*2) { dfs(ls,t-ti[x]*2); dfs(rs,t-ti[x]*2); F(i,ti[x]*2+1,t) F(j,0,i-ti[x]*2) dp[x][i]=max(dp[x][i],dp[ls][j]+dp[rs][i-ti[x]*2-j]); } // cout<<t<<endl; // F(i,1,t) if(dp[x][i]) printf("dp[%d][%d]=%d\n",x,i,dp[x][i]); } signed main() { scanf("%lld",&T); build(1); dfs(1,T); printf("%lld",dp[1][T-1]);//要-1 QAQ return 0; }
[luogu 1270] “訪問”美術館 (樹形dp)