[codeforces][gym101873]2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

本文精选了几道算法竞赛题目并提供了详细的解决方案,包括分层图最短路径、简单DP、二分图匹配等,适用于算法学习和竞赛准备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

队内训练
6题:CDFGIK

C.
nn<=1000n(n<=1000)个游乐场mm<=1000m(m<=1000)条双向边,边长都为TT<=1000T(T<=1000),每个游乐场有一个游乐设施,玩一次第ii个游乐场的游乐设施耗时ti,花费pipi的钱,1<=ti,pi<=106(1<=ti,pi<=106)你可以在一个游乐场玩至少一次游乐设施,你从游乐场1出发,再回到游乐场1,花费时间恰好为XX<=1000X(X<=1000) 的最少花费是多少,如果不存在时间刚好为X的方案则输出“It is a trap.”

题解: 分层图最短路,dis[t][i]dis[t][i] 表示到ii点用时恰好为t的最少花费金钱。

#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
#define INF 1999122700000000LL
#define pa pair<int,int>
using namespace std;
queue<pa>q;
int X,ti,n,m,ne,h[1004];
struct edge{
    int to,nt;
}e[20004];
void add(int u,int v){
     e[++ne].to=v;e[ne].nt=h[u];
     h[u]=ne;
}
int t[1004],p[1004];
ll dis[1004][1004];
bool inq[1004][1004];
int w33ha(){
    ne=0;
    memset(h,0,sizeof(h));
    scanf("%d%d%d",&n,&m,&ti);
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    for(int i=1;i<=n;i++)scanf("%d%d",&t[i],&p[i]);
    for(int i=0;i<=1001;i++)
        for(int j=0;j<=1001;j++)
            dis[i][j]=INF;
    dis[t[1]][1]=p[1];
    q.push(make_pair(t[1],1));
    inq[t[1]][1]=1;
    while(!q.empty()){
        pa x=q.front();q.pop();
        int gt=x.first,gp=x.second;
        if(gt+t[gp]<=X){
            if( dis[gt+t[gp]][gp]>dis[gt][gp]+p[gp]){
                dis[gt+t[gp]][gp]=dis[gt][gp]+p[gp];
                if(!inq[gt+t[gp]][gp]){
                    inq[gt+t[gp]][gp]=1;
                    q.push(make_pair(gt+t[gp],gp));
                }
            }
        }
        for(int i=h[gp];i;i=e[i].nt){
            int tim=gt+ti+t[e[i].to];
            if(tim>X)continue;
            if( dis[tim][e[i].to]>dis[gt][gp]+p[e[i].to]){
                dis[tim][e[i].to]=dis[gt][gp]+p[e[i].to];
                if(!inq[tim][e[i].to]){
                    inq[tim][e[i].to]=1;
                    q.push(make_pair(tim,e[i].to));
                }
            }
        }
        inq[gt][gp]=0;
    }
    if(dis[X][1]==INF)return puts("It is a trap."),0;
    else printf("%lld\n",dis[X][1]);
    return 0;
}
int LiangJiaJun(){
    while(scanf("%d",&X)!=EOF)w33ha();
    return 0;
}

D.队友写的(DFS)
F.队友写的+1(二分图匹配)
G.队友写的+2(皮克定理)
I.给nn个物品,从中取若干个物品,第i个物品价值为xixi,任意两个物品距离>=m>=m,问最大取到的物品价值总和。第一个能取的物品的位置是m+1m+1
(n<=300000,m<=10,xi<=32)(n<=300000,m<=10,xi<=32)

题解:简单DP

#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
using namespace std;
int n,m;
int x[300004];
int f[300004][14];
int w33ha(){
    for(int i=1;i<=n;i++)scanf("%d",&x[i]);
    memset(f,0,sizeof(f));
    int ans=0;
    for(int i=m+1;i<=n;i++){
        for(int j=1;j<m;j++){
            f[i][j+1]=max(f[i][j+1],f[i-1][j]);
        }
        f[i][m]=max(f[i][m],f[i-1][m]);
        f[i][1]=max(f[i][1],f[i-1][m]+x[i]);
        for(int j=1;j<=m;j++)ans=max(ans,f[i][j]);
    }
    printf("%d\n",ans);
    return 0;
}
int LiangJiaJun(){
    while(scanf("%d%d",&n,&m)!=EOF)w33ha();
    return 0;
}

K.nn个人问至多删掉k个人使得被删掉的人的工资总和>=d>=d
签到题(不知为何wa3发,换了写法就A了)

#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
using namespace std;
int n,k,d;
struct Ds{
    char s[14];
    int v;
}a[10004];
inline bool dex(Ds A,Ds B){return A.v>B.v;}
int w33ha(){
    for(int i=1;i<=n;i++){
        scanf("%s",a[i].s+1);
        scanf("%d",&a[i].v);
    }
    sort(a+1,a+n+1,dex);
    int kit=-1,sum=0;
    for(int i=1;i<=k;i++){
        sum+=a[i].v;
    }
    if(sum<d)return puts("impossible"),0;
    else{
        printf("%d\n",k);
        for(int i=1;i<=k;i++){
            printf("%s, YOU ARE FIRED!\n",a[i].s+1);
        }
        return 0;
    }
    return 0;
}
int LiangJiaJun(){
    while(scanf("%d%d%d",&n,&d,&k)!=EOF)w33ha();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值