列表

详情


NC231239. Antinomy之命运的抉择

描述

XCPC宇宙中的大学僧们在大学毕业的时候,主要会有两个职业方向,科研 or 开发。这个选择是因僧而异的。对于一个这一届XCPC宇宙的大学僧来说,其有以下三个属性:

每一个大学僧在XCPC宇宙的大学中进修的时候,有机会去选择去学习或不学习个学习节点。

其中学习节点可以分为两个组:开发、科研。对于每一个组,其中有若干个子类型。对于每一个子类型,有如下三个属性:

XCPC宇宙的的大学僧们在科研学习过程中发现不同类系的学习节点往往有不同的特性:

对于第i个大学僧学习完成之后,总能力值为ability

每一个大学僧都单纯的努力提升自己,以尽可能提升自己的能力值为唯一目标,在提升过程中并不关注能力的类型。但是当他们在毕业面临选择的时候,每个大学僧又会回过头根据已经获得的能力值的组成部分,科研能力值以及开发能力值进行选择。选择规则如下:

输入描述

第一行输入三个整数--该大学僧的开发兴趣加成 , 科研兴趣加成 , 总学习时间

第二行输入两个整数--该大学僧的学习节点数量 , 该大学生科研学习节点依赖关系数

接下去行,第行先输入三个整数--该大学僧第i个学习节点的组类别 , 单次学习花费时间 , 单次学习获得的改组能力值
 - 当且仅当时,第i行再输入一个整数--最多学习开发学习组该子类型的次数

接下去行,第行输入两个整数--表示x_iy_i科研学习前置知识


输出描述

如果该大学僧选择科研,则输出一行一个字符串Scientific Research

如果该大学僧选择开发,则输出一行一个字符串Development


示例1

输入:

383200 506133 20
5 0
1 15 703988 2
1 12 91408 2
2 16 711175
2 13 609477
1 20 944564 1

输出:

Development

示例2

输入:

1 1 20
5 1
1 15 703988 1
2 12 91408
2 10 711175
2 10 609477
1 20 944564 1
3 4

输出:

Scientific Research

示例3

输入:

1 1 20
5 1
1 15 703988 1
2 12 91408
2 10 711175
2 10 609477
1 10 944564 1
3 4

输出:

Development

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 1220ms, 内存消耗: 3624K, 提交时间: 2021-12-16 20:05:36

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3+10,M = 1e5+10;
ll b,c,tot;
struct Node{
    int g,num,cost,a;
};
vector<Node> vec;

int w[M],v[M],cnt[M];
ll dp1[M];
void solve1(){
    int id = 0;
    for(auto & i : vec){
        if(i.g==2) continue;
        int ww = i.cost, vv = i.a, num = i.num;
        int p = 1;
        while(num){
            if(num-p>0){
                w[++id] = ww*p, v[id] = vv*p, num-=p;
                p*=2;
            } else break;
        }
        if(num) w[++id] = ww*num, v[id] = vv*num;
    }
    for(int i=1;i<=id;i++){
        for(int j = (int)tot;j>=w[i];j--){
            dp1[j]=max(dp1[j],dp1[j-w[i]]+v[i]);
        }
    }
}

vector<int> g[N];
int in[N];
ll sumv[N][100],sumw[N][100];
ll dp2[M];
int dfs(int u,int x,int f){
    for(int vv : g[u]){
        sumv[f][x+1] = sumv[f][x]+ vec[vv].a;
        sumw[f][x+1] = sumw[f][x]+ vec[vv].cost;
        return dfs(vv,x+1,f);
    }
    return x;
}

void solve2(int n){
    for(int i=1;i<=n;i++){
        if(in[i]==0&&vec[i].g==2){
            sumv[i][1] = vec[i].a;
            sumw[i][1] = vec[i].cost;
            cnt[i] = dfs(i,1,i);
        }
        else cnt[i]=0;
    }
    for(int i=1;i<=n;i++)
        for(int j=(int)tot;j>=0;j--)
            for(int k=0;k<=cnt[i];k++){
                if(sumw[i][k]<=j) dp2[j] = max(dp2[j],dp2[j-sumw[i][k]]+sumv[i][k]);
            }
}

int main(){
    int n,m;
    scanf("%lld%lld%lld",&b,&c,&tot);
    scanf("%d%d",&n,&m);
    vec.push_back({0,0,0,0});
    for(int i=1;i<=n;i++){
        int gou,num,cost,a;
        scanf("%d",&gou);
        scanf("%d%d",&cost,&a);
        if(gou==1) scanf("%d",&num);
        vec.push_back({gou,num,cost,a});
    }
    for(int i=1,x,y;i<=m;i++){
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        in[y]++;
    }

    solve1();
    solve2(n);
    ll res=0,resid; //开发:1,科研:2
    for(int i=0;i<=tot;i++){
        if(b*dp1[i]+c*dp2[tot-i]>res){
            res = b*dp1[i]+c*dp2[tot-i];
            if(b*dp1[i]>c*dp2[tot-i]) resid = 1;
            else if(b*dp1[i]<c*dp2[tot-i]) resid = 2;
            else resid = (n&1)+1;
        }
    }
    printf("%s\n",(resid==1)?"Development":"Scientific Research");
}

上一题