2016年计蒜客初赛第六场 微软的员工福利(中等)

题目链接:点这里!!!!!


题解:dp(i,u)表示第i个人选第u个显示器为根的子树得到的最大值。然后去枚举i和他二子的最大值和最小值就可以了。

时间复杂度为O(n^3)


代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<vector>
#include<bitset>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cstdlib>
#include<cmath>
#define LL long long
#define pb push_back
#define pa pair<int,int>
#define clr(a,b) memset(a,b,sizeof(a))
#define lson lr<<1,l,mid
#define rson lr<<1|1,mid+1,r
#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)
#define key_value ch[ch[root][1]][0]
#pragma comment(linker, "/STACK:102400000000,102400000000")
const LL  MOD = 1000000007;
const int N = 100+15;
const int maxn = 8e3+15;
const int letter = 130;
const LL INF = 1e18;
const double pi=acos(-1.0);
const double eps=1e-10;
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n;
LL p[N][2],dp[N][2];
int vis[N];
vector<int>G[N],g[N];
stack<int>s;
queue<int>q;
void bfs(int y){
    while(!q.empty()) q.pop();
    while(!s.empty()) s.pop();
    q.push(y);
    vis[y]=1;
    while(!q.empty()){
        int x=q.front();
        q.pop();
        s.push(x);
        for(int i=0;i<G[x].size();i++){
            int to=G[x][i];
            if(!vis[to]){
                g[x].pb(to);
                vis[to]=1;
                q.push(to);
            }
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&p[i][0],&p[i][1]);
        if(p[i][0]>p[i][1]) swap(p[i][0],p[i][1]);
    }
    for(int i=1;i<=n;i++)G[i].clear();
    int x,y;
    for(int i=0;i<n-1;i++){
        scanf("%d%d",&x,&y);
        G[x].pb(y),G[y].pb(x);
    }
    bfs(1);
    LL max1=0,min1=0;
    int c,d,e;
    while(!s.empty()){
        x=s.top(),s.pop();
        if(g[x].size()==0){
            dp[x][0]=p[x][0];
            dp[x][1]=p[x][1];
        }
        else if(g[x].size()==1){
            y=g[x][0];
            for(int pd=0;pd<2;pd++){
                max1=max(p[x][pd],p[y][0]);
                min1=min(p[x][pd],p[y][0]);
                LL p0=(max1-min1+999)/1000*666*x;
                max1=max(p[x][pd],p[y][1]);
                min1=min(p[x][pd],p[y][1]);
                LL p1=(max1-min1+999)/1000*666*x;
                if(dp[y][0]-p0>dp[y][1]-p1) dp[x][pd]=dp[y][0]-p0+p[x][pd];
                else dp[x][pd]=dp[y][1]-p1+p[x][pd];
            }
        }
        else {
            dp[x][0]=dp[x][1]=-INF;
            for(int pd=0;pd<2;pd++){
                for(int u=0;u<2;u++)
                for(int i=0;i<g[x].size();i++)
                for(int v=0;v<2;v++)
                for(int j=0;j<g[x].size();j++){
                    if(i==j) continue;
                    c=g[x][i],d=g[x][j];
                    LL max1=max(p[c][u],p[d][v]);
                    LL min1=min(p[c][u],p[d][v]);
                    if(p[x][pd]<min1||p[x][pd]>max1) continue;
                    LL ans=0;
                    ans=ans+dp[c][u]+dp[d][v];
                    ans=ans-(max1-min1+999)/1000*666*x;
                    int flag=1;
                    for(int k=0;k<g[x].size();k++){
                        LL vs=-INF;
                        if(i==k||j==k)continue;
                        e=g[x][k];
                        if(p[e][1]<min1||p[e][0]>max1||(p[e][0]<min1&&p[e][1]>max1)){flag=0;break;}
                        if(min1<=p[e][0]&&p[e][0]<=max1) vs=dp[e][0];
                        if(min1<=p[e][1]&&p[e][1]<=max1) vs=max(vs,dp[e][1]);
                        ans+=vs;
                    }
                    if(!flag) continue;
                    dp[x][pd]=max(dp[x][pd],ans+p[x][pd]);
                }
            }
            for(int pd=0;pd<2;pd++){
                for(int u=0;u<2;u++)
                for(int i=0;i<g[x].size();i++){
                    c=g[x][i];
                    LL max1=max(p[c][u],p[x][pd]);
                    LL min1=min(p[c][u],p[x][pd]);
                    LL ans=dp[c][u];
                    ans=ans-(max1-min1+999)/1000*666*x;
                    int flag=1;
                    for(int k=0;k<g[x].size();k++){
                        LL vs=-INF;
                        if(i==k)continue;
                        e=g[x][k];
                        if(p[e][1]<min1||p[e][0]>max1||(p[e][0]<min1&&p[e][1]>max1)){flag=0;break;}
                        if(min1<=p[e][0]&&p[e][0]<=max1) vs=dp[e][0];
                        if(min1<=p[e][1]&&p[e][1]<=max1) vs=max(vs,dp[e][1]);
                        ans+=vs;
                    }
                    if(!flag) continue;
                    dp[x][pd]=max(dp[x][pd],ans+p[x][pd]);
                }
            }
        }
    }
    printf("%lld\n",max(dp[1][0],dp[1][1]));
    return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值