动态规划基础题(第2题):累积和问题,华丽丽超时

博客讨论了AtCoder比赛中的一个题目,涉及动态规划和累积和的概念。原始题解由于暴力求解导致超时,后来的解决方案通过预处理优化达到了线性时间复杂度,从而避免了超时问题。文章提供了两种解法的代码实现,并给出了多组测试用例及其输出。
摘要由CSDN通过智能技术生成

碎碎念

  • 看似越简单问题里面越有陷阱,本题最初的题解华丽丽的有4个case超时。
    • AtCode的比赛,要么0分,要么100,二选一

标签

  • 动态规划、累积和

合集

  • 【动态规划】累积和

题目地址

010 - Score Sum Queries

  • https://atcoder.jp/contests/typical90/tasks/typical90_j

问题描述

ABC 大学には N 人の一年生が在籍しています。クラスは 2 つあり、学籍番号 i 番の生徒のクラスは C i _i i 組です。今日は期末試験が返却され、学籍番号 i 番の生徒の点数は P i _i i 点でした。

以下の形式の質問が Q 個与えられます。j = 1, 2, … \dots , Qそれぞれについて答えてください。

  • 学籍番号 L j _j j ∼ \sim R j _j j 番の 1 組生徒における、期末試験点数の合計
  • 学籍番号 L j _j j ∼ \sim R j _j j 番の 2 組生徒における、期末試験点数の合計
  • これら 2 つの値をそれぞれ求めよ。

制約

  • 1 ≤ \leq N ≤ \leq 100000
  • 1 ≤ \leq C i _i i ≤ \leq 2
  • 0 ≤ \leq P i _i i ≤ \leq 100
  • 1 ≤ \leq Q ≤ \leq 100000
  • 1 ≤ \leq L j _j j ≤ \leq R j _j j ≤ \leq N
  • 入力は全て整数

入力

入力は以下の形式で標準入力から与えられます。

N
C1 P1
C2 P2
⋮
CN PN
Q
L1 R1
L2 R2
⋮
LQ RQ

出力

学籍番号 L j _j j ∼ \sim R j _j j番の 1 組生徒における期末試験点数の合計を A j _j j、学籍番号 L j _j j ∼ \sim R j _j j 番の 2 組生徒における期末試験点数の合計を B j _j j として、以下の形式で出力してください。

A1 B1
A2 B2
⋮
AQ BQ

入力例 1

7
1 72
2 78
2 94
1 23
2 89
1 40
1 75
1
2 6

出力例 1

63 261

学籍番号 2 ∼ \sim 6 番の 1 組生徒における、期末試験合計点は 23+40=63 です。
また、学籍番号 2 ∼ \sim 6 番の 2 組生徒における、期末試験合計点は 78+94+89=261 です。


入力例 2

7
1 72
2 78
2 94
1 23
2 89
1 40
1 75
10
1 3
2 4
3 5
4 6
5 7
1 5
2 6
3 7
1 6
2 7

出力例 2

72 172
23 172
23 183
63 89
115 89
95 261
63 261
138 183
135 261
138 261

入力例 3

1
1 100
3
1 1
1 1
1 1

出力例 3

100 0
100 0
100 0

一方の組の生徒が存在しないケースもあります。


入力例 4

20
2 90
1 67
2 9
2 17
2 85
2 43
2 11
1 32
2 16
1 19
2 65
1 14
1 51
2 94
1 4
1 55
2 90
1 89
1 35
2 81
20
3 17
5 5
11 11
8 10
3 13
2 6
3 7
3 5
12 18
4 8
3 16
6 8
3 20
1 12
1 6
5 16
3 10
17 19
4 4
7 15

出力例 4

175 430
0 85
0 65
51 16
116 246
67 154
0 165
0 111
213 184
32 156
175 340
32 54
299 511
132 336
67 244
175 314
51 181
124 90
0 17
120 186

题解

小码匠

  • 很暴力,很超时,华丽丽掉进陷阱
  • 时间复杂度:ON
void coder_solution() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    vector<pair<int, long long >> c_p(n);
    for (int i = 0; i < n; i++) {
        cin >> c_p[i].first >> c_p[i].second;
    }
    int q;
    cin >> q;
    int temp, temp_2;
    long long dp_1 = 0;
    long long dp_2 = 0;
    for (int i = 0; i < q; i++) {
        cin >> temp >> temp_2;
        for (int j = temp - 1; j < temp_2; j++) {
            if (c_p[j].first == 1) {
                dp_1 += c_p[j].second;
            } else {
                dp_2 += c_p[j].second;
            }
        }
        cout << dp_1 << " " << dp_2 << endl;
        dp_1 = 0;
        dp_2 = 0;
    }
}

小码匠二次题解

  • AC
  • 时间复杂度:O+N
void best_solution() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    vector<long long> one(n + 1);
    vector<long long> tow(n + 1);
    one[0] = 0;
    tow[0] = 0;
    long long C, P;
    for(int i = 1; i <= n; i++) {
        cin >> C >> P;
        if(C == 1) {
            one[i] = one[i - 1] + P;
            tow[i] = tow[i - 1];
        } else {
            tow[i] = tow[i - 1] + P;
            one[i] = one[i - 1];
        }
    }
    int q;
    cin >> q;
    int L, R;
    for(int i = 0; i < q; i++) {
        cin >> L >> R;
        cout << one[R] - one[L - 1] << " " << tow[R] - tow[L - 1] << endl;
    }
}

待补知识点

  • 继续学习累积和
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码匠和老码农

喜欢作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值