蓝桥杯普及模拟赛 C[01背包变形] & D[树边多次统计]

 

 

C. 春季特惠

描述

JM编程平台的春季特惠开始了,你决定购买一些编程课程。

现在你一共有X元的预算,该平台上所有的n个课程均有折扣,标号为i的课程的原价a_i元,现价只要b_i元(也就是说该课程可以优惠a_i-b_i元)并且你购买该课程能获得充实值为w_i

由于优惠的存在,你可能做出一些冲动消费导致最终买课程的总费用超过预算,但只要满足获得的总优惠金额不低于超过预算的总金额,那在心理上就不会觉得吃亏。

现在你希望在心理上不觉得吃亏的前提下,获得尽可能多的充实值。

输入

第一行包含两个整数nX

接下来n行包含每个课程的信息,原价a_i, 现价b_i,能获得的充实值为w_i ,均为整数。

输出

输出一个数字,表示你能获得的最大充实值

样例

输入

4 100
100 73 60
100 89 35
30 21 30
10 8 10

输出

100

输入

3 100 
100 100 60
80 80 35
21 21 30

输出

60

输入

2 100
100 30 35
140 140 100

输出

135

提示

样例1解释

购买1、3、4三门课程,获得总优惠38元,总金额102元超预算2元,满足条件,获得100充实值。

数据规模

对于30\%的数据,n<=15

对于另外30\%的数据,n<=100

对于100\%的数据,n<=500,0<=X<=10000,0<=b_ i<=a_i<=500,1<=w_i<=10^7

 

D. 树的家园

[HAOI2015]树上染色
gym102222 G. Factories
CCF 201909-5 城市规划
    (难度递减顺序)
的弱化版 

 

描述

春天来啦,小松鼠们纷纷跑了出来。

它们(一共2\times n只松鼠)聚集到了一颗有2\times n个节点的树上,有2\times n - 1条边,每一条边连接了u_i,v_i,边权为w_i。每个节点都有一颗它们心爱的松果,所以它们刚刚好一人一个位置

大树觉得,松鼠不能随便排位置,不然会有损自己的形象,于是给松鼠们下了一个难题:

假定第i只松鼠在p_i位置,并且第i只松鼠和第i+n只松鼠是好基友(i\le n)。

我们定义dist(u,v)表示节点u和节点v的简单路径上边的边权之和。

那么,你需要计算出\sum_{i=1}^{n}dist(p_i,p_{i+n}) 的最大值和最小值。

大树答应它们,只要它们能顺利解决这道题,就把松果全送给它们当食物。

松鼠们为难了,你能帮帮它们吗?

输入

第一行,输入一个数n

接下来2\times n - 1行,每一行输入三个数u_i,v_i,w_i,表示有一条连接u_iv_i,边权为w_i的双向边。

输出

输出两个数,分别表示最大值和最小值,用一个空格隔开。

样例

输入

2
1 2 1
1 3 2
1 4 3

输出

6 6

提示

数据规模

对于5 \%的数据,1\le n\le 5

对于10\%的数据,1\le n\le 10

对于30 \%的数据,1\le n\le 100

对于50 \%的数据,1\le n\le 1000

对于70\%的数据,1\le n\le 10^5

对于100\%的数据,1\le n\le 5\times 10^5

数据保证这2\times n - 1条边能构成一颗树,并且边权w_i\le 2\times 10^7

 

C

#include<stdio.h>
#define max(a,b) ((a)>(b)?(a):(b))
const int N=505,M=3e5+5;
int n,m,X,v[N],w[N];long long ans,f[M];
int main(){
    //freopen("input.txt","r",stdin);
    scanf("%d%d",&n,&X);
    for(int i=1,x,y,z;i<=n;i++){
        scanf("%d%d%d",&x,&y,&z);
        if(2*y<=x) X+=x-2*y,ans+=z;
        else{
            ++m;
            v[m]=2*y-x;w[m]=z;

        }
    }
    for(int i=1;i<=m;i++){
        for(int j=X;j>=v[i];j--){
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
    }
    ans+=f[X];
    printf("%lld\n",ans);
    return 0;
}

 

D

#include<vector>
#include<stdio.h>
using namespace std;
#define mp make_pair
#define fi first
#define se second
#define pb emplace_back
typedef pair<int,int> pir;
typedef unsigned long long ull;
const int N=1e6+5;
template<typename T>
inline void read(T &x){
    register bool f=0;register char ch=getchar();x=0;
    for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
    if(f) x=-x;
}
template<typename T,typename...Args>
void read(T &x,Args&...args){read(x);read(args...);}
int n,m,siz[N];ull ans1,ans2;
vector<pir>g[N];
void dfs(int x,int fa){
    siz[x]=1;
    for(auto &t:g[x]){
        int &y=t.fi;
        int &z=t.se;
        if(y!=fa){
            dfs(y,x);
            siz[x]+=siz[y];
            ans1+=1ULL*min(siz[y],n-siz[y])*z;
            if(siz[y]&1) ans2+=z;
        }
    }
}
int main(){
    read(n);n<<=1;
    for(int i=1,x,y,z;i<n;i++) read(x,y,z),g[x].pb(mp(y,z)),g[y].pb(mp(x,z));
    dfs(1,1);
    printf("%llu %llu\n",ans1,ans2);
    return 0;
}

 

posted @ 2020-04-17 11:00  神犇(shenben)  阅读(310)  评论(0编辑  收藏  举报