【Codeforces gym102890M】Mathematics society problem | greedy

Topic link: original link

Main idea:

Given a string of numbers, from 1 − 9 1-919 composition, and then for each number1 ≤ i ≤ 9 1\le i \le 91i9 The number of items to be deleted. After deleting, what is the largest number that can be formed?

Question idea:

Before other oj ojo j has done a similar original question, the original question is:

Given a string of numbers, delete mmAfter m numbers, make the number of remaining numbers the largest

Looking at this question in this way, you only need to consider the decision-making nature. Assume a location iii can be deleted, it must satisfysi <si + 1 s_i <s_{i+1}si<si+1, This sample si s_isiAfter deleting, it will let si + 1 s_{i+1}si+1Substitution makes the weight of this position larger, so you only need to simulate from front to back.

If the deletion is complete and there are still opportunities for deletion, then for the final sequence, it must be monotonous and non-increasing. At this time, deleting the previous number will only cause more changes 不优, so it is enough to delete from back to front at this time.

So how to consider this question?

First of all, the first idea to get the question is to imitate the above idea. Because of the restrictions, it is only necessary to judge whether the bit can be deleted when it is deleted. Then the final sequence must look like:

  • 如果 s i < s i + 1 s_i < s_{i+1} si<si+1, Then si s_isiIt must be impossible to delete
  • 否则 s i > s i + 1 s_i > s_{i+1} si>si+1, Must be satisfied

After writing, WA — — 17 WA — 17W A 1 7 , think about it carefully, for a numberxxIf x is larger than the previous one, the previous one will be deleted, but if the last number must be deleted, then this number may be deleted if it is larger than the next one.

E.g:

38978 38978 38978 —— 8 8 8 to delete1 11 time,9 99 to delete1 11 time
According to our simulation, when9 9When 9 comes,8 88 throw away, finally delete 9 to
get:378 3783 7 8
can actually get:387 3873 8 7
because9 99 must be thrown away, but he has thrown away the optimal solution, so you only need to judge which numbers must be thrown away, you don't need to use it to throw away the previous numbers.

So just add a special sentence.

Code:

/*** keep hungry and calm CoolGuang!  ***/
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e17+7;
const ll maxn = 1e7+700;
const ll mod= 998244353;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
    
    char c=getchar();T x=0,f=1;while(!isdigit(c)){
    
    if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
    
    x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
char s[maxn];
char st[maxn];
int top = 0;
int up[15],cop[15];
int vis[maxn];
int main(){
    
    
	scanf("%s",s+1);
    for(int i=1;i<=9;i++) scanf("%d",&up[i]);
    n = strlen(s+1);
	for(int i=1;i<=n;i++) cop[s[i]-'0']++;
	for(int i=1;i<=n;i++){
    
    
		if(up[s[i]-'0'] == cop[s[i]-'0']){
    
    
			cop[s[i]-'0']--;
			up[s[i]-'0']--;	
			continue;
		}
		while(top && up[st[top]-'0'] && s[i] > st[top]){
    
    
			up[st[top]-'0']--;
			top--;
		}
		st[++top] = s[i];
		cop[st[top]-'0']--;
	}
	for(int k=1;k<=top;k++)
		printf("%c",st[k]);
	printf("\n");
    return 0;
}
/***
12152
1 1 0 0 0 0 0 0 0
1 2 3 4 5 6 7 8 9
***/

Guess you like

Origin blog.csdn.net/qq_43857314/article/details/112797609