把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

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分啥都写了结果匹配忘记怎么写了我丢人我自闭)
posted @ 2019-08-18 19:49  fluoce  阅读(199)  评论(0编辑  收藏  举报

Contact with me