• JZ训练记录Day18


    T1

    Description

    “封印大典启动,请出Nescafe魂珠!”随着圣主applepi一声令下,圣剑护法rainbow和魔杖护法freda将Nescafe魂珠放置于封印台上。封印台是一个树形的结构,魂珠放置的位置就是根节点(编号为0)。还有n个其他节点(编号1-n)上放置着封印石,编号为i的封印石需要从魂珠上获取Ei的能量。能量只能沿着树边从魂珠传向封印石,每条边有一个能够传递的能量上限Wi,魂珠的能量是无穷大的。作为封印开始前的准备工作,请你求出最多能满足多少颗封印台的能量需求?

    注意:能量可以经过一个节点,不满足它的需求而传向下一个节点。每条边仅能传递一次能量。

    Input

    第一行一个整数n,表示除根节点之外的其他节点的数量。

    接下来n行,第i+1行有三个整数Fi、Ei、Wi,分别表示i号节点的父节点、i号节点上封印石的能量需求、连接节点i与Fi的边最多能传递多少能量。

    Output

    最多能满足多少颗封印石的能量需求。

    Data Constraint

    对于100%的数据,满足1<=n<=1000,0<=Fi<=n,0<=Ei,Wi<=100
     
    Solution:
    考虑树形dp,把每个点的需求抽象为代价,即可转化为背包问题
    设Dp[i][j]表示根为i的子树下花费j点能量可以满足的最多点
    然后背包转移即可
    考场因为不熟练写挂了,遗憾
    貌似贪心取最小点也可以A
    Code:
    #include<bits/stdc++.h>
    using namespace std;
    #define re register
    inline int MAX(int a,int b)<% return (a>b)?a:b; %>
    int N,son[1005][1005],tot[1005],E[1005],W[1005],Fa[1005],Ans;
    int Dp[1005][105];//Dp[i][j]表示根为i的子树下花费j点能量可以满足的最多点 
    void dfs(int Pos){
        for(int i=E[Pos];i<=W[Pos];i++) Dp[Pos][i]=1;
        if(tot[Pos]==0) return;
        for(re int i=1;i<=tot[Pos];++i){
            dfs(son[Pos][i]);
        }
        for(re int i=1;i<=tot[Pos];i++){
                for(re int j=W[Pos];j>=0;j--)
                    for(re int k=0;k<=W[son[Pos][i]]&&j>=k;k++)
                        Dp[Pos][j]=MAX(Dp[Pos][j-k]+Dp[son[Pos][i]][k],Dp[Pos][j]);    
        }
    }
    int main()
    {
        scanf("%d",&N);
        for(int i=1;i<=N;i++){
            scanf("%d",&Fa[i]);
            scanf("%d%d",&E[i],&W[i]);
            son[Fa[i]][++tot[Fa[i]]]=i;
            if(Fa[i]==0) W[0]+=W[i];
        }
        for(int i=1;i<=tot[0];i++){
            dfs(son[0][i]);
            Ans+=Dp[son[0][i]][W[son[0][i]]];
        }
        cout<<Ans;
        return 0;
    }

    T2

    Description

    “圣主applepi于公元2011年9月创造了Nescafe,它在散发了16吃光辉之后与公元2011年11月12日被封印为一颗魂珠,贮藏于Nescafe神塔之中。公元2012年9月,圣主带领四大护法重启了Nescafe,如今已经是Nescafe之魂的第30吃传播了。不久,它就要被第二次封印,而变成一座神杯。。。”applepi思索着Nescafe的历史,准备着第二次封印。

    Nescafe由n种元素组成(编号为1~n),第i种元素有一个封印区[ai,bi]。当封印力度E小于ai时,该元素获得ai的封印能量;当封印力度E在ai到bi之间时,该元素将获得E的封印能量;而当封印力度E大于bi时,该元素将被破坏从而不能获得任何封印能量。现在圣主applepi想选择恰当的E,使得封印获得的总能量尽可能高。为了封印的最后一击尽量完美,就请你写个程序帮他计算一下吧!

    Data Constraint

    对于50%的数据,1<=N<=1000,1<=ai<=bi<=10000。

    对于100%的数据,1<=N<=10^5,1<=ai<=bi<=10^9。
     
    Solution:
    因为玄学的原因所以结果肯定是某个端点??
    排序之后从小到大进行枚举即可,处理结果巧妙使用两个P1和P2(详见代码)。
    Code:
    #include<bits/stdc++.h>
    typedef long long LL;
    using namespace std;
    int A[100500],tot,B[100500],Pos,N;
    LL P1,P2;
    struct Node
    {
        LL Val,prio;
    }C[100500*2];
    LL Ans;
    
    int cmp(Node a,Node b){
        return a.Val<b.Val||(a.Val==b.Val&&a.prio>b.prio);
    }
    int main()
    {
        Ans=-1e9-7;
        scanf("%d",&N);
        for(int i=1;i<=N;i++){
            scanf("%d%d",&A[i],&B[i]);    
            P1+=A[i];
            C[++tot].Val=A[i];C[tot].prio=1;
            C[++tot].Val=B[i];C[tot].prio=0;
        }
        sort(C+1,C+tot+1,cmp);
        for(int i=1;i<=tot;i++)
            if(C[i].prio==1){
                P1-=C[i].Val;P2++;
                LL Sum=1ll*C[i].Val*P2+1ll*P1;
                if(Ans<Sum) <%Ans=Sum; Pos=C[i].Val; %>
            }
            else {
                LL Sum=1ll*C[i].Val*P2+1ll*P1;
                if(Ans<Sum) <%Ans=Sum; Pos=C[i].Val; %>
                P2--;
            }        
        printf("%d %lld",Pos,Ans);
        return 0;
    }

     

    T3

     

    Description:

    Data Constraint

    对于30%的数据,M<=20;

    对于80%的测试点,M<=200;

    对于100%的测试点,1<=N<=100,1<=M<=100000。
     
    Solution:
    80分把每个*看做分隔符然后按顺序匹配同时枚举m次来表示不同的循环同构串。
    100分未知
    Code:(80分啥都写了结果匹配忘记怎么写了我丢人我自闭)
  • 相关阅读:
    Mysql中的递归查询
    让git忽略对已经版本控制的文件的本地修改
    关于c#中逆变和协变的理解
    把之前的相关博客都迁到了博客园~
    结合github pages使用travis CI
    Spring中的Filter、HandlerInterceptor和AOP
    HDU1711 Number Sequence 题解 KMP算法
    HDU1358 Period 题解 KMP算法
    HDU1686 Oulipo 题解 KMP算法
    HDU3336 Count the string 题解 KMP算法
  • 原文地址:https://www.cnblogs.com/Takarada-Rikka/p/11373628.html
Copyright © 2020-2023  润新知