zoukankan      html  css  js  c++  java
  • 1774:大逃杀

        1774:大逃杀
        
        时间限制: 1000 ms         内存限制: 262144 KB
        提交数: 49     通过数: 19
        【题目描述】
        
        将地图上的所有地点标号为1到n,地图中有n-1
        
        条双向道路连接这些点,通过一条双向道路需要一定时间,保证从任意一个点可以通过道路到达地图上的所有点。
        
        有些点上可能有资源,到达一个有资源的点后,可以获取资源来增加 wi的武力值。
        
        资源被获取后就会消失,获取资源不需要时间。可选择不获取资源。
        
        有些点上可能有敌人,到达一个有敌人的点后,必须花费ti秒与敌人周旋,并将敌人消灭。敌人被消灭后就会消失。不能无视敌人。
        
        如果一个点上既有资源又有敌人,必须先消灭敌人才能获取资源。
        
        游戏开始时Y君可以空降到任意一个点上,接下来,有T秒时间行动,Y君希望游戏结束时,武力值尽可能大。
        【输入】
        
        第一行由单个空格隔开的两个正整数 n,T,代表点数和时间。
        
        第二行n个由单个空格隔开的非负整数代表 wi,如果wi=0表示该点没有资源。
        
        第三行n个由单个空格隔开的非负整数代表 ti,如果ti=0代表该点没有敌人。
        
        接下来n-1行每行由单个空格隔开的3个非负整数a,b,c表示连接a和b的双向道路,通过这条道路需要c秒。
        
        【输出】
        
        输出一行一个整数代表T秒后Y君的武力值。
        
        【输入样例】
        
        17 54
        5 5 1 1 1 25 1 10 15 3 6 6 66 4 4 4 4
        0 1 3 0 0 0 1 3 2 0 6 7 54 0 0 0 0
        1 8 3
        2 8 3
        8 7 7
        7 13 0
        7 14 0
        15 14 2
        16 14 3
        17 14 5
        7 9 4
        9 10 25
        10 11 0
        10 12 0
        7 6 20
        3 6 3
        3 4 3
        3 5 3
        
        【输出样例】
        
        68
        
        【提示】
        
        【数据规模】
        对于100%的数据,n,T≤300,0≤wi,ti,c≤106,1≤a,b≤n。

    【题解】

    因为起点不确定,所以定义三种状态f,g,h[i][j]分别表示在i子树内用了j的时间,f:从i出发,去了子树内在回到i最大收益,g:从i出发,到达子树内任意节点,h从子树内出发,经过i到达子树内任一节点最大收益。根据子树内信息依次转移即可。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=305;
    int f[N][N],g[N][N],h[N][N],last[N],size,w[N],t[N],n,T,ans;
    struct pigu
    {
        int dao,ne,quan;
    }a[N<<1];
    inline void lingjiebiao(int x,int y,int z)
    {
        a[++size].dao=y;
        a[size].quan=z;
        a[size].ne=last[x];
        last[x]=size;
    }
    //f表示下去了回来,g表示下去了不回来,h表示从下头来 
    inline void dfs(int now,int fa)
    {
        if(t[now]>T) return;
        for(int i=last[now];i;i=a[i].ne)
        {
            if(a[i].dao==fa) continue;
            dfs(a[i].dao,now);
            for(int j=T;j>=t[now];j--)
            {
                for(int k=j-a[i].quan;k>=t[now];k--)
                {
                    int h1=f[now][k],h2=g[now][k],h3=h[now][k];//k表示之前用了好多时间了。 
                    int shen=j-k-a[i].quan;
                    if(shen>=t[a[i].dao])
                    {
                        g[now][j]=max(g[now][j],h1+g[a[i].dao][shen]);
                        h[now][j]=max(h[now][j],h2+g[a[i].dao][shen]); 
                    }
                    shen-=a[i].quan;
                    if(shen>=t[a[i].dao])
                    {
                        g[now][j]=max(g[now][j],h2+f[a[i].dao][shen]);
                        f[now][j]=max(f[now][j],f[a[i].dao][shen]+h1);
                        h[now][j]=max(h[now][j],h3+f[a[i].dao][shen]);
                        h[now][j]=max(h[now][j],h[a[i].dao][shen]+h1);
                    }
                }
                ans=max(ans,h[now][j]);
            }
        } 
    }
    int main()
    {
        cin>>n>>T;
        for(int i=1;i<=n;i++) cin>>w[i];
        for(int i=1;i<=n;i++) 
        {
            cin>>t[i];
            if(t[i]<=T)
                f[i][t[i]]=g[i][t[i]]=h[i][t[i]]=w[i];
        }
        for(int i=1,x,y,z;i<=n-1;i++)
        {
            cin>>x>>y>>z;
            lingjiebiao(x,y,z);
            lingjiebiao(y,x,z);
        }
        dfs(1,0);
        cout<<ans;
    } 
    View Code
  • 相关阅读:
    ELM学习
    《进化》从孤胆极客到高效团队
    《人件》《PeopleWare》 【美】Tom DeMarco TimothyLister 著 肖然 张逸 滕云 译
    《进化》从孤胆极客到高效团队---Notes1
    大数据第一部分LInux学习Note1
    C#Windows窗体初学
    C#初学笔记(Windows编程的基本概念)
    C#学习2017-9-26(读取文本文件和读取二进制文件)Notes9
    C#学习2017-9-26Notes8(文件和流,FileStream类)
    C#学习笔记Notes8(接口,接口实现,程序集,命名空间,using)
  • 原文地址:https://www.cnblogs.com/betablewaloot/p/12247208.html
Copyright © 2011-2022 走看看