gym 100543 CERC 2014 L Outer space invaders

本文解析了一道关于在限定时间内使用炸弹消灭敌人的算法题目。通过对比错误的动态规划解法,介绍了正确的官方题解思路,即将问题转化为寻找覆盖特定线段集所需的最小总线段长度,最终利用区间动态规划求解。

Problem

Central Europe Regional Contest 2014
vjudge.net/problem/Gym-100543L

Meaning

有 n 个敌人,第 i 个将在 ai 时间出现、 bi 时间开枪、距离为 di
你有一种炸弹,可随意设置爆炸范围 R,引爆后在 R 以内的、已经出现的敌人会被炸死,消耗 R 格燃料。
要在任何一个敌人出现后、开枪前([ ai , bi ])消灭他,问最小消耗。

Analysis

当时的错误想法:先按( ai , bi )字典序排序,然后dp:
dp[i]:及时搞掂前 i 个敌人的最小消耗
对于最后一个敌人 i,可能跟着最后的若干的敌人一起被炸,于是转移:
dp[i] = min { dp[j] + cost( j+1 , i ) | 0<=j<i }
其中 cost( j+1 , i )是从第 j+1 个到第 i 个敌人里最远的距离(因为是一起炸),且要满足条件:min { bj+1 , … , bi1 } ai ,这样才能等在一起炸。
但这样是错的,排序有毒,有考虑不到的情况,如反例:

1
3
1 4 10
2 2 1
3 4 11

这样是要 1、3 一起炸,2 单独炸。
官方题解是把敌人理解成一条条从( ai , di )到( bi , di )的水平线段,炸弹就是从( xi , 0)到( xi , R)的竖直线段,横线被竖穿过就是敌人被炸弹炸到。
于是把所有时刻(a 和 b)离散化后,用区间dp
dp[s][e]:与所有完全包含在时间段 [ s , e ] 内的所有横线的最小竖线长度和
(暂时没完全理解 :( …)

Accepted Code

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 300, D = 10000, BIG = N * D;

struct node
{
    int a, b, d;
} al[N];

int ts[N<<1|1], dp[N+1<<1][N+1<<1] = {{0}};

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n;
        scanf("%d", &n);
        int m = 0;
        for(int i = 0; i < n; ++i)
        {
            scanf("%d%d%d", &al[i].a, &al[i].b, &al[i].d);
            ts[++m] = al[i].a;
            ts[++m] = al[i].b;
        }
        sort(ts + 1, ts + m + 1);
        m = unique(ts + 1, ts + m + 1) - ts - 1;
        for(int i = 0; i < n; ++i)
        {
            al[i].a = lower_bound(ts + 1, ts + m + 1, al[i].a) - ts;
            al[i].b = lower_bound(ts + 1, ts + m + 1, al[i].b) - ts;
        }
        for(int w = 0; w < m; ++w)
            for(int s = 1; s + w <= m; ++s)
        {
            int e = s + w, id = -1;
            for(int i = 0; i < n; ++i)
                if(s <= al[i].a && al[i].b <= e && (id == -1 || al[i].d > al[id].d))
                    id = i;
            if(id == -1)
            {
                dp[s][e] = 0;
                continue;
            }
            dp[s][e] = BIG;
            for(int k = al[id].a; k <= al[id].b; ++k)
                dp[s][e] = min(dp[s][e], dp[s][k-1] + al[id].d + dp[k+1][e]);
        }
        printf("%d\n", dp[1][m]);
    }
    return 0;
}

Wrong DP

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 300;

struct node
{
    int a, b, d;
    bool operator < (const node &rhs) const
    {
        return a == rhs.a ? b < rhs.b : a < rhs.a;
    }
} arr[N+10];

int dp[N+10];

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n;
        scanf("%d", &n);
        for(int i=1; i<=n; ++i)
            scanf("%d%d%d", &arr[i].a, &arr[i].b, &arr[i].d);
        sort(arr + 1, arr + n + 1);
        dp[0] = 0;
        for(int i=1; i<=n; ++i)
        {
            dp[i] = dp[i-1] + arr[i].d;
            int r = arr[i].d;
            for(int j=i-1; j; --j)
            {
                if(arr[j].b < arr[i].a)
                    break;
                r = max(r, arr[j].d);
                dp[i] = min(dp[i], dp[j-1] + r);
            }
        }
        printf("%d\n", dp[n]);
    }
    return 0;
}
The issue of finding the *SpaceInvaders* game ROM, or any other ROM for that matter, stems from the fact that distributing copyrighted ROMs without permission constitutes a violation of intellectual property rights. Gym, which previously provided ROMs for use with its reinforcement learning environments, ceased distribution to comply with legal standards[^1]. For those seeking to work with *SpaceInvaders* or similar games in a legal and sustainable manner, there are several options: 1. **Obtaining ROMs Legally**: If the user owns a physical or digital copy of the game, they may be permitted under certain jurisdictions to create a personal backup (i.e., a ROM) for archival purposes. This is often subject to strict legal conditions and varies by country[^1]. 2. **Open-Source Alternatives**: Some open-source projects recreate classic games or provide environments that closely mimic them without using copyrighted ROMs. For example, the ALE (Arcade Learning Environment) project offers a legal way to interact with Atari 2600 games by requiring users to supply their own ROMs, but also provides guidance on how to legally obtain them through homebrew or personal backups[^1]. 3. **Research and Educational Frameworks**: Platforms like RetroArch, alongside legal cores such as ProSystem (for Atari 2600 emulation), can be used with legally obtained ROMs. Researchers or educators may find partnerships with copyright holders or institutions that provide access to historical software for non-commercial use. 4. **Commercial Platforms**: Some classic games, including *SpaceInvaders*, are available for purchase on modern platforms such as the Nintendo Switch Online service, PlayStation Store, or Steam. These versions are officially licensed and offer a way to play the game while respecting copyright[^1]. 5. **Homebrew and Fan Remakes**: There are also fan-made or inspired versions of classic games that do not use original assets and are thus free to distribute. These can often be found on platforms like itch.io or GitHub. If the goal is to use *SpaceInvaders* in a machine learning context, it is advisable to explore frameworks that allow for integration with user-provided ROMs, ensuring compliance with licensing and copyright laws. ```python # Example of using Gym with a local ROM (assuming legal access to the ROM) import gym env = gym.make('SpaceInvaders-v0') observation = env.reset() for _ in range(1000): action = env.action_space.sample() observation, reward, done, info = env.step(action) if done: break env.close() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值