P1323 删数游戏(技巧)

Posted liuz8848

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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("
");
    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;
}

以上是关于P1323 删数游戏(技巧)的主要内容,如果未能解决你的问题,请参考以下文章

题解删数游戏

Android课程---Android Studio使用小技巧:提取方法代码片段

VS2015使用技巧 打开代码片段C#部分

26个jQuery代码片段使用技巧

VS中添加自定义代码片段——偷懒小技巧

提效小技巧——记录那些不常用的代码片段