码迷,mamicode.com
首页 > 其他好文 > 详细

P1270 “访问”美术馆

时间:2020-03-28 13:08:08      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:遇到   one   题意   can   root   opened   bit   pac   std   

题意:给出一颗树形图,每一条边都有一定权值,叶子节点里面有若干副画

      现在有一个小偷要进去偷画,每一条边的权值就是走的时间,偷画需要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\n",dp[1][n]);
35     return 0;
36 }
View Code

 

P1270 “访问”美术馆

标签:遇到   one   题意   can   root   opened   bit   pac   std   

原文地址:https://www.cnblogs.com/pangbi/p/12586719.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!