Jeanny
寂兮,寥兮,独立不改,周行而不殆

打地鼠游戏:

1.小C最近在研究一个打地鼠的游戏,游戏开始时,所有的地鼠都会出现在游戏的界面中,每个地鼠有两个属性:消失的时间t和分数s(即在第一秒到t秒之间打中地鼠就能获得s的分数,时间为t+1秒时,地鼠消失)。小C点击鼠标打一只地鼠的时间是1秒,打中之后地鼠会消失。给定n只地鼠的消失时间和分数,小C想知道他在这场游戏中最多能得到多少分数?

每组数据第一行,包含一个整数n,表示地鼠的数量\(1\le n\le 10^4\)

接下来的每行,表示这只地鼠消失的时间\(1\le t_i\le 10^4\),每只地鼠可以获得分数\(2\le s_i\le 10^4\)

暴力+贪心
可以从大到小枚举分数,分数大的优先打,找空位的时间,如果没有空位时间了,打不了这只。复杂度o(n*T)

#include <bits/stdc++.h>
using namespace std;

struct node {
    long long time;
    long long score;
};

node ls[100005];
bool vis[100005];

bool cmp(node n1, node n2) { return n1.score > n2.score; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    long long n;
    cin >> n;
    long long time, score;
    for (long long i = 0; i < n; i++) {
        cin >> time >> score;
        ls[i] = (node){ time, score };
    }
    sort(ls, ls + n, cmp);
    long long sum = 0;
    for (long long i = 0; i < n; i++) {
        for (long long j = ls[i].time; j >= 1; j--) {
            if (!vis[j]) {
                vis[j] = true;
                sum += ls[i].score;
                break;
            }
        }
    }
    cout << sum << '\n';
    return 0;
}
// by zsx

2.每组数据第一行,包含一个整数n,表示地鼠的数量\(1\le n\le 10^4\)。接下来的每行,表示这只地鼠消失的时间\(1\le t_i\le 10^9\),每只地鼠可以获得分数\(2\le s_i\le 10^9\)

分析:如果题目改成,有一些其他限制(比如瓷砖,比如飞盘队),前i只地鼠,打或者不打,获得的最大分数。很自然想到,前i个地鼠打j个的最大分数。
dfs(int i, int j, int sum){ dfs(i+1,j,sum); dfs(i+1,j+1,sum+a[i].v)};
那么限制条件是什么?

极小状态集:打了j个,j不仅表示的是最少用了j秒。
dp[i][j] 前i-1个地鼠,打了j-1个,相当于占用了j-1秒,已经求出来最大得分了。那么第i只地鼠,要不要打?因为前面已经占用了j-1秒,因此,第i只地鼠的消失时间必须大于j-1,即>=j,才能打。复杂度o(n^2)

#include <iostream>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
int n, dp[3][10005], ans, T;
//每个时间有一张券,当前的地鼠消失的时间很晚为a[i].t,那么券就会给你很多,如果前面已经打了j只,则用了i张券,这样a[i].t
//- j >= 0
struct Node {
    int t, s;
} a[10005];
bool cmp(Node x, Node y) { return x.t < y.t; }
signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i].t >> a[i].s;
    sort(a + 1, a + n + 1, cmp);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            if (a[i].t - j >= 0)
                dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j - 1] + a[i].s);
            else
                dp[i % 2][j] = max(dp[i % 2][j], dp[(i - 1) % 2][j]);
            if (i == n)
                ans = max(ans, dp[n % 2][j]);
        }
    }
    cout << ans << endl;
    /*
    o
    o
    o . o
    */
    return 0;
}

posted on 2024-03-29 21:11  Jeanny  阅读(168)  评论(0)    收藏  举报