DAY2 模拟考试第三题 情书的代价

3、情书的代价
(cost.pas/c/c++)
【题目描述】
在如今的应试教育下,“以学业为重”成为了分手的主要理由。佳佳想知道写情书到底会花去多少时间以决定是否值得牺牲这些时间来讨好GirlFriend。他得到了一份Evalls的所有情书的副本,他希望从中得知Evalls写这些情书最少花了多少时间。
完成每封情书需要花费不同的时间。写完第i封情书需要Ti个单位的时间。从情书的内容上看,某些情书有前后呼应的关系,这决定了一些情书的写作时间有先后关系。因此,佳佳可以得到若干个这样的信息:哪封情书一定是在哪封情书写完之后才写的。我们假设Evalls每天最多花t个单位时间来写情书。如果时间足够,一天里可以写多封情书;但一封情书必须在一天里完成,不能分成若干天来写。佳佳想知道,Evalls最少花了多少天来完成所有的情书。
【输入格式】
输入文件名为cost.in
第一行输入两个用空格隔开的正整数n和t,表示情书的总数和每天最多花费的时间。
第二行有n个用空格隔开的正整数,其中,第i个数表示写第i封情书需要花费的时间Ti。
以后若干行每行有两个用空格隔开的正整数x和y,表示第x封情书要在第y封情书之前完成。
输入数据总保证所有情书可以在有限的时间内完成,因此你不需要考虑无解的情况。
【输出格式】
输出文件名为cost.out
输出一个正整数,表示完成所有的情书最少需要几天。
【样例输入】
3 5
2 3 4
1 3
3 2
【样例输出】
3
【数据规模】
对于所有数据,n ≤ 30,t ≤ 300 000。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<queue>
using namespace std;
#define maxn 500005
#define LL unsigned long long
LL n,ans,rest,num_e,t;
struct edge{
    LL to,nex;
}e[maxn];
LL dis[maxn],cost[maxn],head[maxn],rd[maxn];
bool v[maxn];
void add(LL x,LL y){
    rd[y]++;
    e[++num_e].to=y;e[num_e].nex=head[x];head[x]=num_e;
}
void read(LL x){
    if(rest>=cost[x]) rest-=cost[x];
    else{
        ans++;
        rest=t-cost[x];
    }
}
queue<LL> q;
int main(){
    freopen("cost.in","r",stdin);
    freopen("cost.out","w",stdout);
    scanf("%llu%llu",&n,&t);
    for(LL i=1;i<=n;i++) scanf("%llu",&cost[i]);
    LL a,b;
    while(scanf("%llu%llu",&a,&b)==2) add(a,b);

    for(LL i=1;i<=n;i++){
        if(!rd[i]) q.push(i),v[i]=1;
    }
    while(!q.empty()){
        LL x=q.front();q.pop();
        read(x);
        for(LL i=head[x];i;i=e[i].nex){
            if(!v[e[i].to]){
                q.push(e[i].to);
               v[e[i].to]=1;
            }
        }
    }
    printf("%llu",ans);
    return 0;
}

这是80分代码。。。。。改不过来啦啊啊啊啊啊

#include<cstdio>
using namespace std;
int n, limit, x, y;
int t[35], ans;
int mem[35][35];
int f[35][35], size[35], topo[35], in[35];
int w[35][35], Size[35];
int q[35], front, rear;
void maketopo()
{
     front = 1; rear = 1;
     for(int i = 1; i <= n; i++) if(in[i] == 0) q[rear++] = i;
     while(front < rear)
       {
        int u = q[front]; front++;
        for(int i = 1; i <= size[u]; i++)
           {
            in[f[u][i]]--;
            if(in[f[u][i]] == 0) q[rear++] = f[u][i];
           }
       }
     topo[0] = 0;
     for(int i = 1; i <= n; i++) topo[q[i]] = i;
     return;
}
bool vis[35];
void dfs(int day, int use, int pre)
{
     int finish = 0;
     for(int i = 1; i <= n; i++) if(!vis[i]) { finish = i; break; }
     if(finish == 0){
        if(day<ans) ans=day;
        return;
       }
     int tot = 0;
     for(int i =finish; i <= n; i++) if(! vis[i]) tot += t[i];
     if(day + tot / limit >= ans) return;
     bool canfinish = false;
     for(int i = finish; i <= n; i++) if(! vis[i])
        {
         bool ok = true;
         for(int j = 1; j <= Size[i]; j++) if(!vis[w[i][j]]) { ok = false; break; }
         if(ok && use + t[i] <= limit && topo[i] > topo[pre])
           { canfinish = true; break; }
        }
     for(int i = finish; i <= n; i++) if(! vis[i])
        {
         bool ok = true;
         for(int j = 1; j <= Size[i]; j++) if(!vis[w[i][j]]) { ok = false; break; }
         if(! ok) continue;
         vis[i] = true;
         if(use + t[i] <= limit && topo[i] > topo[pre]) dfs(day, use + t[i], i);
         else if(! canfinish) dfs(day + 1, t[i], 0);
         vis[i] = false;
        }
     return;
}
int main(){
    freopen("cost.in", "r", stdin);
    freopen("cost.out", "w", stdout);
    scanf("%d%d", &n, &limit);
    for(int i = 1; i <= n; i++) scanf("%d", &t[i]);
    while(scanf("%d%d", &x, &y) == 2) mem[x][y] = 1;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++) if(i != j && mem[i][j] == 1){
            in[j]++;
            size[i]++; f[i][size[i]]=j;
            Size[j]++; w[j][Size[j]]=i;
           }
    maketopo();
    ans = n;
    dfs(1, 0, 0);
    printf("%d\n", ans);
    return 0;
}

我搞到了标程

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务