P1270 “访问”美术馆
Posted pangbi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1270 “访问”美术馆相关的知识,希望对你有一定的参考价值。
题意:给出一颗树形图,每一条边都有一定权值,叶子节点里面有若干副画
现在有一个小偷要进去偷画,每一条边的权值就是走的时间,偷画需要5秒
给出警察到来时间,问最多能偷多少副画
思路:这是一道树形dp
我们遍历每个节点,从根节点dfs到叶子节点,那么如何进行状态转移呢
我们用一个dp【i】【j】表示在i节点花掉j时间能偷到的最多的画
那么我们在计算某个节点能够偷到画的数量的时候
先把走廊的时间算上去,假如走廊需要走5秒,那么我们就需要10秒(来回走)
然后就开始枚举在这个节点的时候,花掉k时间能过拿到最多的画的数量
然后遇到有分岔路的一个节点的时候,我们就需要枚举这两边,花掉k时间能过拿到最多的画的数量
那么如何求呢?同样我们得先算上走廊的时间再进行枚举
假如到了根节点位置,走廊来回走花了10秒,那么我们在算花55秒能够偷到画的最多数量的时候,就只能用45秒
然后逐一枚举时间即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e3+10; 4 int dp[maxn][maxn]; 5 int cnt=0; 6 int n; 7 void dfs() 8 { 9 int root=++cnt; 10 int limit,tmp; 11 scanf("%d%d",&limit,&tmp); 12 limit*=2; 13 if(tmp){ 14 for(int i=limit;i<=n;i++){ 15 dp[root][i]=min(tmp,(i-limit)/5); 16 //在此节点能够偷到的画的最多数量 17 } 18 } 19 else{ 20 int left=cnt+1; dfs(); 21 int right=cnt+1; dfs(); 22 for(int i=limit;i<=n;i++){ 23 int tmp=i-limit; //减去走廊所用时间,剩下的就是能够用的时间 24 for(int j=0;j<=tmp;j++){ 25 dp[root][i]=max(dp[root][i],dp[left][j]+dp[right][tmp-j]); 26 } 27 } 28 } 29 } 30 int main() 31 { 32 scanf("%d",&n); n--; 33 dfs(); 34 printf("%d ",dp[1][n]); 35 return 0; 36 }
以上是关于P1270 “访问”美术馆的主要内容,如果未能解决你的问题,请参考以下文章