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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
包含章节:课后习题答案 第1章数字媒体技术概论 1.1媒体及其特性 1.1.1媒体概念 1.1.2媒体特性 1.2数字媒体及其特性 1.2.1数字媒体概念 1.2.2数字媒体特性 1.2.3数字媒体传播模式 1.3数字媒体技术的研究领域 1.3.1数字媒体内容产业 1.3.2数字媒体技术发展趋势 1.3.3数字媒体技术研究领域 1.3.4数字媒体应用领域 练习与思考 第2章数字音频技术基础 2.1音频技术及其特性 2.1.1音频的概念及特性 2.1.2模拟音频记录设备及特性. 2.1.3模拟音频处理设备 2.2音频数字化 2.2.1数字音频 2.2.2音频的数字化过程 2.3数字音频质量及格式 2.3.1音频数据率及质量 2.3.2声音文件格式 2.4数字音频的编辑技术 2.4.1数字音频的编辑方式 2.4.2数字音频设备 2.4.3数字音频编辑软件简介 2.4.4数字音频编辑实例 2.5数字音频技术应用 练习与思考 第3章数字图像的处理技术 3.1图像颜色模型 3.1.1视觉系统对颜色的感知 3.1.2RGB颜色模型 3.1.3CMYK颜色模型 3.1.4HSB颜色模型 3.1.5YUV与YIQ颜色模型 3.1.6CIELab颜色模型 3.2彩色空间的线性变换 3.2.1YUV与RGB彩色空间变换 3.2.2YIQ与RGB彩色空间变换 3.2.3HSI(HSB)与RGB之间的转换 3.2.4YCrCb与RGB彩色空间变换 3.3图像的基本属性及种类 3.3.1分辨率 3.3.2颜色深度 3.3.3真彩色、伪彩色与直接色 3.3.4图像的大小及种类 3.4数字图像的获取技术 3.4.1位图的获取设备与技术 3.4.2矢量图的获取设备与技术 3.5图像创意设计与编辑技术 3.5.1图像处理软件简介 …… 第4章数字视频及编辑 第5章数字动画技术 第6章游戏设计技术 第7章数字媒体的Web集成与应用 第8章数字媒体压缩技术 第9章数字媒体存储技术 第10章数字媒体管理与保护 第11章数字媒体的传输技术 第12章数字媒体技术发展趋势
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值