P1323 删数游戏(技巧)

技巧:给你一个数,要求你删去\(m\)位使得剩下的数最大

这是一个贪心问题,假设原来的数字是\(k\)位,那么相当于要保留\(k-m\)位。
有下面几种贪心策略
\(1.\)每次找最大的保留,直到\(k-m\)个,这样显然是错的,因为要求删除后顺序不能改变。
\(2.\)找到最大的且最靠前的位置,保留它,再从它后面这样操作,直到选够\(k-m\),这样显然也是错的,假如要保留\(4\)位,数据为\(123987\),直接选取\(9\)没办法凑够\(k-m\)个
于是有了下面这种贪心:

设\(L=1,R=m+1\)
考虑\(1-m+1\)位必须选取一个,如果不选取那么后面的\(k-m-1\)位都选也凑不够\(k-m\),所以在前\(1-m+1\)位选取一个最大的数,记他的位置为\(i\),将它加入答案,然后让\(L=i+1,R++\)
这样为什么是对的?
\(1.\)合法性,第一次要在\(1-m+1\)里选择一个数,第二次在\(i+1-m+2\)里选择一个数。每次选择的时候区间\(L-R\)至少有一个数,一定可以选择,每次选择且只选择\(1\)个。如此选了\(m-k\)次,每次右端点\(+1\),一定可以选出长度为\(m-k\)的答案\((1)\);
而且每次选完保证下一次在这个数的后面选,不会出现顺序不合法的情况\((2)\)。
\(2.\)最优性,每个数都会被考虑,比如“第一次要在\(1-m+1\)里选择一个数,第二次在\(i+1-m+2\)里选择一个数”这个过程,根据答案合法性,第一个数一定出自\(1-m+1\),第二个数一定出自\(1-m+2\),所以这样控制区间没有情况会被漏下,且每次选取最大值保证了合法的基础上最优。

总复杂度最坏是\(O(n^2)\),最好是\(O(n)\)

下面是一道相关题目
题面

\(Code\)

#include<cstdio>
#include<iostream>
#include<queue>
#define maxn 30010
#define re register
using namespace std;
priority_queue<int,vector<int>,greater<int> > q;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int m,k,tmp,CNT,cnt;
int need,t[maxn],a[maxn];
char s[10001000],tcc[10001000];
void get_num(int x)
{
    CNT=0;
    while(x)
    {
        tcc[++CNT]='0'+x%10;
        x/=10;
    }//注意这里是倒序,别弄错了
    for(re int i=CNT;i>=1;--i) s[++cnt]=tcc[i];
}
int main()
{
    k=read(),m=read();
    q.push(1);
    for(re int i=1;i<=k;++i)
    {
        tmp=q.top();
        q.pop();
        get_num(tmp);
        a[i]=tmp;
        q.push(2*tmp+1);
        q.push(4*tmp+5);
    }
    int L=1,R=m+1;
    for(re int i=1;i<=k;++i) printf("%d",a[i]);
    printf("\n");
    while(L<=R&&R<=cnt)
    {
        int maxx=0;
        for(re int i=L;i<=R;++i)
        {
            if((s[i]-'0')>maxx) {maxx=s[i]-'0';L=i+1;}//下次从这后面遍历就行
        }
        printf("%d",maxx);
        R++;//下面这个区间也一定有一个解
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Liuz8848/p/11712125.html

时间: 2024-09-29 18:29:08

P1323 删数游戏(技巧)的相关文章

【题解】删数游戏

题目描述 输入一个高精度的正整数n(≤240位),去掉其中任意s个数字后,剩下的数字按原左右次序组成一个新的正整数.编程对给定的n和s,寻找一种方案,使得剩下的数字组成的新数最小. 输入格式 第一行,一个正整数n: 第二行,s(s<n的位数). 输出格式 最后剩下的最小数. 输入样例 175438 4 输出样例 13 题解 容易想到,把当前的数转换成一个数字串,那么这个数字串里如果出现了逆序对,就删除这个逆序对的第一个元素即可.如果不存在逆序对,就删除最后一位即可. #include <ios

细数捕鱼游戏软件开发的游戏技巧,趣味性十足遵循经典套路设计

捕鱼游戏作为深海捕鱼游戏从出现就吸引了很多人的目光,并且在随着技术的发展和进步下,手机捕鱼游戏开发也逐渐的愈演愈烈,甚至是成为了当下流行的投资运营选择.其实在手机捕鱼游戏开发下的捕鱼游戏蕴含了许多还没有被玩家了解透彻的游戏技巧,仍然需要玩家在捕鱼游戏中自己慢慢的发现与总结.欢迎咨询电话:15315986100:QQ:3410861822 手机捕鱼游戏开发,华软打造值得玩 谈及捕鱼游戏的游戏技巧很多人都认为捕鱼游戏就是简单的点击屏幕进行发射就好,账户金币没有了就等着系统的补助发放,丝毫不去想如何捕

数独游戏技巧(转)

引用 数独游戏技巧(图解) 一直都有在玩数独 一般难度的都能完成 可是高难度的就完全没办法了 好多累计玩了几十小时都解不出 刚刚在网上看到这个介绍数独技巧的帖子 真的很实用 不过方法太多 得慢慢消化... 引用 地狱大坏蛋 的 数独游戏技巧(图解) i)唯一数法 :如果我们发现某个格子中只有一个可用候选数,那么这个格子必然是这个数字,这就是唯一数法如下面例子,H5格子中只有唯一候选数3 ii)隐含唯一数法 如果我们发现某一行某一列或某个九宫有一个候选数只出现在一个格子里面,那么这个格子必然是这个

猜数游戏-不知道为什么不能输汉字

#include<stdio.h>#include<stdlib.h> int main(){ printf("************猜数游戏*************\n"); printf("***********1:开始游戏***********\n"); printf("***********2:退出游戏***********\n"); printf("***********3:游戏介绍********

Silverlight 2.5D RPG游戏技巧与特效处理:(十一)AI系统

Silverlight 2.5D RPG游戏技巧与特效处理:(十一)AI系统 作者: 深蓝色右手  来源: 博客园  发布时间: 2011-04-19 11:18  阅读: 1282 次  推荐: 0                   原文链接   [收藏] 谈到人工智能(AI),这个话题就太大了:大学里有<人工智能教程>专门讲这方面的知识,什么大名鼎鼎的人工神经网络.遗传算法等等均可一窥究竟,这里如赘述似乎有些班门弄斧,我们暂且丢它一边去吧. 本节,我的主要目的是与大家共同探讨AI在RPG

简单猜数游戏2

/*简单猜数游戏,magic number#2,版本*/#include<stdio.h>#include<stdlib.h> int main(void){ int magic; /*magic number*/ int guess; /*user's guess*/ printf("\nWelcome to the magic number game\n"); magic=rand(); /*产生随机数*/ printf("\nGuess the

简单猜数游戏1

/*简单猜数游戏,magic number#1,版本*/#include<stdio.h>#include<stdlib.h> int main(void){ int magic; /*magic number*/ int guess; /*user's guess*/ printf("\nWelcome to the magic number game\n"); magic=rand(); /*产生随机数*/ printf("\nGuess the

codevs4096 删数问题

题目描述 Description 键盘输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对给定的N 和S,寻找一种方案使得剩下的数字组成的新数最小. 输入数据均不需要判错. 输出组成的新的正整数.(N不超过240位) 输入描述 Input Description 第一行,输入一正整数N(N<=10240),表示要删的数: 第二行,输入一正整数S,表示删去的个数,当然S小于N的位数. 输出描述 Output Description 仅一行,输出删数后形

BZOJ 1978: [BeiJing2010]取数游戏 game( dp )

dp(x)表示前x个的最大值,  Max(x)表示含有因数x的dp最大值. 然后对第x个数a[x], 分解质因数然后dp(x) = max{Max(t)} + 1, t是x的因数且t>=L ----------------------------------------------------------------------------------------- #include<cstdio> #include<cmath> #include<cstring>