【CSP】2022-12-2 训练计划 递推但是有坑(重点不是优化是坑)(完美的犯了两次)

2022-12-2 训练计划 递推但是有坑(重点不是优化是坑)(完美的犯了两次)

这题其实并不难,但是有一个坑你如果只用题目的数据的话一定想不到,得自己造数据才能发现。就是我们的思路总是片面的想不到那么全面,可是也没有好的办法来一下提升自己思路的全面的问题,只能我们就是得自己根据题目造一些数据,去发现隐藏在题目中的限制。

我们的思路总是根据题目给出的数据想出来的,那么我们的思路就有可能只符合这个数据,想要拓宽拿满分我们就要造一些数据,**就是不管怎么样,我们都要做点什么,不能卡住了就不动了,**那样肯定不能改进。

思路

我们其实很容易看到题目就刻意的想要让你用递归(也包含一点贪心的思想),这点其实大多数人都能想出来。

求最早开始时间,我们可以发现每个科目的最早开始时间只跟他的前置依赖科目有关(算是马尔可夫性吧hhh),然后我们求这个科目的最早开始时间就是通过前置依赖科目的最早开始时间计算的,而且自己依赖的科目又在自己的前面,保证了更新自己前依赖科目已经更新了。

求最晚开始时间,我们可以想到,就是每个科目的最晚开始时间是跟自己的后置依赖科目有关,然后就像求最早开始时间一样求最晚开始时间,只不过是反过来遍历。(注意这里有坑,后面会提到)

遇到的问题(学到的东西)

发现这次刷出现的问题和上次出现的简直不要一摸一样,看来我还是没有在犯错中长进,人真的很难改进错误,就像狗改不了吃shit呢hhhh

但是还是希望这次记住了以后不要再犯了。

  1. 依赖数量问题

一开始以为只要存储被依赖的项目就可以,但是还是根本过不了,

后来才发现被依赖的数量不止一个,就是一个项目可以被多个项目依赖,但是一个项目就只能依赖一个项目。我们不知不觉的就假设了一个课程只被一个课程依赖,但是实际并不是这样的。

  1. 求最晚开始时间

一开始还以为等价的为只要看被依赖项目的时间谁最长就记录下来,发现根本不行,必须要看被依赖项目的开始时间谁最早才行。因为被依赖的项目的时间最长,不一定最早,得看最早开始时间。
在这里插入图片描述

完整代码

#include <bits/stdc++.h>
using namespace std;
int n, m;
int p[10001], t[10001];
vector<int> c[10001]; // 对应i课程的后置课程
int min_start[101], max_start[101];
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
    {
        cin >> p[i];
        c[p[i]].push_back(i);
    }
    for (int i = 1; i <= m; i++)
    {
        cin >> t[i];
    }
    int maxTime = -1;
    for (int i = 1; i <= m; i++)
    {
        if (p[i] == 0)
        {
            min_start[i] = 1;
        }
        else
        {
            min_start[i] = min_start[p[i]] + t[p[i]];
        }
        maxTime = max(maxTime, min_start[i] + t[i] - 1);
    }
    for (int i = 1; i <= m; i++)
    {
        cout << min_start[i] << ' ';
    }
    if (maxTime <= n)
    {
        for (int i = m; i > 0; i--)
        {
            if (c[i].empty())
            {
                max_start[i] = n - t[i] + 1;
            }
            else
            {
                int max_time = c[i][0];
                for (int j = 0; j < c[i].size(); j++)
                {
                    if (max_start[c[i][j]] < max_start[max_time])
                    {
                        max_time = c[i][j];
                    }
                }
                max_start[i] = max_start[max_time] - t[i];
            }
        }
        cout << endl;
        for (int i = 1; i <= m; i++)
        {
            cout << max_start[i] << ' ';
        }
    }
    return 0;
}
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值