• 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;
    }
    
  • 相关阅读:
    Algs4-1.3链表实现泛型可迭代Stack
    Algs4-1.3链表实现科泛型可迭代Bag
    Algs4-1.3链表实现不定容泛型Queue不支持迭代
    Algs4-1.3不定容数组实现泛型栈支持迭代
    Algs4-1.3链表实现不定容泛型Stack不支持迭代
    Algs4-1.3不定容泛型栈(不可迭代)
    Algs4-1.3定容字符串栈
    Algs4-1.3定容泛型栈
    Algs4-1.3E.W.Dijkstra双栈算术表达式求值算法
    Algs4-1.2(非习题)可视化累加器
  • 原文地址:https://www.cnblogs.com/Liuz8848/p/11712125.html
Copyright © 2020-2023  润新知