gym 101170 NWERC 2016 A Arranging Hat

31 篇文章 0 订阅

Problem

Northwestern European Regional Contest 2016
vjudge.net/problem/Gym-101170A

Meaning

给出 n 个位数为 m 的数字(前导零补足),可以通过改变某些数上的某些位置上的数字,使得该 n 个数字是非降序排列。求在总改动位数最少的情况下,改完后的 n 个数字(m 位)。

Analysis

一个很神奇的DP:
dp[i][j]:对前 i 个数做 j 次修改后得到的(满足非降序前提下)最小的第 i 个数
从合法的 dp[i][j] 开始推 dp[i+1][j+k]:尝试在 dp[i][j] 基础上再加 k 次操作,贪心地构造出尽可能小的数(先尝试跟 dp[i][j] 相等,不行的话就找个尽量低的位 +1,然后该位后面尽量置 0),来更新 dp[i+1][j+k],并记住转移的路径。
最后在 dp[n][0] ~ dp[n][?] 里找第一个合法的状态,并根据转移路径将找出答案序列。‘?’是指最多的总操作次数,极限是 N×M ,但官方题解说不超过 N×log10N ,而 1<log1040<2

Official Solution

  1. Let’s consider whole numbers without splitting them by digits.
  2. ai,j = the minimum number obtainable for i-th number, if we made j changes on the first i numbers.
  3. From any state we can try changing some amount of digits in the i +1-th number.
  4. Then we can greedily in O(M) obtain the smallest number we can get from i +1-th number using fixed number of changes.
  5. If it’s greater or equal than ai,j – that’s a valid transition.
  6. O(N2M) for the state and O(M2) for the transition.
  7. But the answer is never going to be more than Nlog10N .
  8. O(N2log10N) for the state and O(Nlog10NM) for the transition.

Tips

  • 按 dalao 的代码来看,从 dp[i][j] 推 dp[i+1][j+k] 时,好像不能保证 k 次修改机会一定会被用完,所以 dp 的定义应该是:对前 i 个数做不超过 j 次修改后得到的(满足非降序前提下)最小的第 i 个数
  • 题目应该有 special judge?我的代码跑不出第二个样例的参考答案(而是更优),也过了

Code

#include <cstdio>
#include <cstring>
using namespace std;
const int N = 40, M = 400;

char v[N+1][M+2]; // origin number string
char tmp[M+2]; // constructed number string
char dp[N+1][N<<1][M+2]; // or "string dp[N+1][N<<1]"
bool valid[N+1][N<<1]; // whether dp[i][j] is reachable
char *ans[N+1]; // answer sequence
int pre[N+1][N<<1]; // pre-status mark

bool construct(char *now, char *nxt, int m, int k)
{
    // Plan A:
    // get close to "now"
    int num = k, pos;
    strcpy(tmp, nxt);
    if(!k) // special judge whether k = 0
        return strcmp(tmp, now) >= 0;
    for(pos = 0; pos < m && num > 0; ++pos)
        if(tmp[pos] != now[pos])
        {
            tmp[pos] = now[pos];
            --num;
        }
    if(strcmp(tmp, now) >= 0)
        return true;

    // Plan B:
    // +1 at smallest possible digit (where "pos" is)
    // and set most possible 0 after that

    // can't +1 at digit '9'
    for(--pos; pos >= 0 && now[pos] == '9'; )
        --pos;
    if(pos < 0)
        return false;
    num = k;
    strcpy(tmp, nxt);
    // keep consistency with "now" before "pos"
    for(int i = 0; i < pos /* && num > 0 */; ++i)
        if(tmp[i] != now[i])
        {
            tmp[i] = now[i];
            --num;
        }
    // +1 at "pos"
    if(tmp[pos] != now[pos] + 1)
    {
        tmp[pos] = now[pos] + 1;
        --num;
    }
    // set 0 after "pos"
    for(++pos; pos < m && num > 0; ++pos)
        if(tmp[pos] != '0')
        {
            tmp[pos] = '0';
            --num;
        }
    return true;
}

int main()
{
    int n, m;
    scanf("%d%d%*c", &n, &m);
    for(int i = 1; i <= n; ++i)
        scanf("%s", v[i]);

    memset(valid, false, sizeof valid);
    for(int i = 0; i < m; ++i)
        dp[0][0][i] = '0';
    dp[0][0][m] = '\0';
    valid[0][0] = true;

    for(int i = 0; i < n; ++i)
        for(int j = 0; j < n << 1; ++j)
    {
        if(!valid[i][j])
            continue;
        for(int k = 0; k <= m && j + k < n << 1; ++k)
            if(construct(dp[i][j], v[i+1], m, k) &&
                (!valid[i+1][j+k] || strcmp(tmp, dp[i+1][j+k]) < 0))
            {
                valid[i+1][j+k] = true;
                strcpy(dp[i+1][j+k], tmp);
                pre[i+1][j+k] = j;
            }
    }

    int p;
    for(p = 0; p < n << 1; ++p)
        if(valid[n][p])
            break;
    for(int i = n; i > 0; p = pre[i][p], --i)
        ans[i] = dp[i][p];
    for(int i = 1; i <= n; ++i)
        puts(ans[i]);
    return 0;
}
自2020年以来,自动驾驶汽车(Autonomous Vehicle)在这一领域取得了显著进展。 自动驾驶汽车通过使用先进的传感技术,如雷达、激光雷达和摄像头,以及深度学习和人工智能算法,实现了车辆的自主驾驶。它们能够感知周围环境,了解道路状况,并做出相应的决策和行驶动作,从而实现无需人类操控的车辆行驶。 自动驾驶汽车在2020年迅速崭露头角。它们的技术日益成熟,不断的实验和测试表明其在安全性和性能方面已经取得了显著的突破。虽然仍然存在一些挑战,比如在复杂城市环境中导航和处理紧急情况,但这些问题正经过不断的研究和改进来得以解决。 在未来,自动驾驶汽车有望在各个领域发挥重要作用。首先,它们将可以提高道路交通的安全性。由于自动驾驶车辆不受人类司机的疲劳、分心和驾驶误差的限制,它们的驾驶能力更为稳定和准确。其次,自动驾驶汽车还能够提高交通效率。通过与其他车辆实时通信和协同,它们可以避免交通堵塞和减少事故发生,从而减少交通拥堵和行车时间成本。 此外,自动驾驶汽车也将为交通出行带来便利和舒适性。乘客可以更轻松地进行其他活动,如工作、休息或娱乐,而不必担心驾驶问题。老年人和残障人士也将能够自由独立地出行,提高他们的生活质量。 综上所述,作为2020年的重要趋势,自动驾驶汽车具有广阔的应用前景。通过不断的创新和发展,它们将在道路交通安全、交通效率和出行体验方面取得进一步的提升。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值