CF1209

CF1209

A B

Regardless of questions of water

C

Because eventually the whole sequence is required to be monotonous

So we consider the enumeration breakpoint \ (x \)

After the \ (<x \) number into a first set

The \ (> x \) of the second set into a number

As \ (= x \) number

He can put the first set if and only if there is no back \ (<x \) number

Otherwise, it is necessary to put the second set

Put in the time to judge the legitimacy

(Enumerate the \ (0-9 \) wrote \ (1--10 \) is gone QAQ

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 5e5 + 3;
char s[N];
int a[N];
int sum[N][11];
int belong[N];
int n;
inline int read(){
    int v = 0,c = 1;char ch = getchar();
    while(!isdigit(ch)){
        if(ch == '-') c = -1;
        ch = getchar();
    }
    while(isdigit(ch)){
        v = v * 10 + ch - 48;
        ch = getchar();
    }
    return v * c;
}
inline bool check(int x){
//  printf("x::%d\n",x);
    int now1 = -1,now2 = -1;
    for(int i = 1;i <= n;++i){
    //  printf("%d %d %d\n",i,now1,now2);
        if(a[i] < x && a[i] < now1) return 0;
        if(a[i] > x && a[i] < now2) return 0;
        if(a[i] != x){
            if(a[i] < x) now1 = max(now1,a[i]),belong[i] = 1;
            else if(a[i] > x) now2 = max(now2,a[i]),belong[i] = 2;
        }
        if(a[i] == x){
            bool flag = 0;
            for(int j = 0;j <= x - 1;++j) if(sum[i][j]) flag = 1;
            if((!flag) && (a[i] >= now1)) {
                now1 = a[i],belong[i] = 1;  
            }
            else{
                if(now2 > a[i]) return 0;   
                now2 = max(now2,a[i]),belong[i] = 2;
            }
        }
    }
    return 1;
}
int main(){
    int T = read();
    while(T--){
        bool flag = 0;
        n = read();
        scanf("%s",s + 1);
        for(int i = 1;i <= n;++i) a[i] = s[i] - '0';
        for(int i = n;i >= 1;--i){
            for(int j = 0;j <= 9;++j) sum[i][j] = sum[i + 1][j]; 
            sum[i][a[i]]++;
        } 
        for(int i = 0;i <= 9;++i){
            if(check(i)){
                for(int j = 1;j <= n;++j) printf("%d",belong[j]);
                printf("\n");
                flag = 1;
                break;
            }
        }
        if(!flag) printf("-\n");
        for(int i = 1;i <= n;++i){
            for(int j = 0;j <= 9;++j) sum[i][j] = 0;    
        }
    }
    return 0;
}
 

D

First, we found that the \ (a_i \) to \ (B_i \) connected side eventually forming a plurality of communication block

Each communication block size of 1 - is the contribution of this communication block

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 5e5 + 3;
struct node{
    int ai;
    int bi; 
}a[N];
vector <int> G[N];
int n,k;
bool flag1[N],flag2[N];

inline int read(){
    int v = 0,c = 1;char ch = getchar();
    while(!isdigit(ch)){
        if(ch == '-') c = -1;
        ch = getchar();
    }
    while(isdigit(ch)){
        v = v * 10 + ch - 48;
        ch = getchar();
    }
    return v * c;
}
queue <int> q;
int ans = 0;
inline void dfs(int x){
    flag1[x] = 1;ans++;
    for(int i = 0;i < (int)G[x].size();++i){
        int y = G[x][i];
        if(!flag1[y]) dfs(y);   
    }
}
int main(){
    n = read(),k = read();
    for(int i = 1;i <= k;++i){
        a[i].ai = read();
        a[i].bi = read();
        G[a[i].ai].push_back(a[i].bi);
        G[a[i].bi].push_back(a[i].ai);  
    }
    for(int i = 1;i <= n;++i) if(!flag1[i]) ans--,dfs(i);
    cout << k - ans;
}

E1E2

First observed \ (n-\) are very small, when a number less than or equal \ (20 \) when the first reaction is to consider the shape pressure

A particularly important property

After we put all the columns in accordance with the maximum value of this column descending run Xu

At most before \ (n \) columns helpful

That

n-$ \ Times m \ (matrix becomes \) n-\ $ a n-Times

We set \ (f_ {i, S} \) represents the former \ (I \) column, \ (S \) a maximum value corresponding to the state of this line has been determined that the greatest contribution,

\ (g_ {i, S} \) represents from \ (I \) column extraction can be represented by \ (S \) the maximum value of this set

Transfer
\ [f_ {i, S}
= \ max_ {T \ subseteq S} f_ {i - 1, S - T} + g_ {i, T} \] down consider how to find \ (G \)

Due to the presence of rotation

We enumerate a collection, then all the states are represented in this collection can try to update the value of this collection

such as

\ (1101 \) can represent \ (1101 \) , \ (1110 \) , \ (1011 \) , \ (0111 \)

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int M = 21;
const int N = 2003;
int a[M][N];
int b[M][M];
int n,m;
int f[13][(1 << 13) + 5];
int g[13][(1 << 13) + 3];
struct node{
    int maxx;
    int id;
}row[N];
inline bool cmp(node x,node y){
    return x.maxx > y.maxx; 
}
inline int read(){
    int v = 0,c = 1;char ch = getchar();
    while(!isdigit(ch)){
        if(ch == '-') c = -1;
        ch = getchar();
    }
    while(isdigit(ch)){
        v = v * 10 + ch - 48;
        ch = getchar();
    }
    return v * c;
}
int main(){
    int T = read();
    while(T--){
        memset(g,0,sizeof(g));
        memset(f,0,sizeof(f));
        memset(row,0,sizeof(row));
        n = read(),m = read();
        for(int i = 1;i <= n;++i){
            for(int j = 1;j <= m;++j){
                a[i][j] = read();
                row[j].maxx = max(row[j].maxx,a[i][j]);     
                row[j].id = j;
            }
        }
        sort(row + 1,row + m + 1,cmp);    
        m = min(n,m);
        for(int i = 1;i <= n;++i){
            for(int j = 1;j <= m;++j)
                b[i][j] = a[i][row[j].id];
        }
        for(int j = 1;j <= m;++j){
            for(int i = 1;i < (1 << n);++i){
                int res = i;
                int sum = 0;
                for(int h = 0;h < n;++h) if(res & (1 << h)) sum += b[h + 1][j];
                for(int k = 0;k < n;++k){   
                    g[j][res] = max(g[j][res],sum);
                    int nn = res;
                    res = ((nn >> (n - 1)) & 1) | ((nn << 1) & ((1 << n) - 1));
                }
            }
        }
        for(int i = 0;i < m;++i){
            for(int j = 0;j < (1 << n);++j){
                int S = ((1 << n) - 1) ^ j;
                f[i + 1][j] = max(f[i + 1][j],f[i][j]);
                for(int son = S;son;son = (son - 1) & S){
                    f[i + 1][j | son] = max(f[i + 1][j | son],f[i][j] + g[i + 1][son]); 
                }
            }
        }
        printf("%d\n",f[m][(1 << n) - 1]);
    }
    return 0;
}

G1

We have found that if such a thing exists

3 1 3 1 3

Then the entire interval will be the same number of final

That

We set \ (l_i \) represents \ (i \) position of the first occurrence, \ (r_i \) represents \ (i \) position of the last occurrence

Finally, this will happen

We found the intersection zone will eventually become the same number, that number becomes the largest in this range depending on the number of times that number appears

We all come up interval to run a race greedy

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 5e5 + 3;
int a[N];
int fir[N],las[N];
int sum[N];
int n,q;
bool flag1 = 1,flag2 = 1;
inline int read(){
    int v = 0,c = 1;char ch = getchar();
    while(!isdigit(ch)){
        if(ch == '-') c = -1;
        ch = getchar();
    }
    while(isdigit(ch)){
        v = v * 10 + ch - 48;
        ch = getchar();
    }
    return v * c;
}
int ans = 0x3f3f3f3f;
struct node{
    int li;
    int ri; 
    int id;
};
vector <node> G;
inline bool cmp(node x,node y){
    return x.li < y.li || (x.li == y.li && x.ri > y.ri);
}
int main(){
    n = read(),q = read();
    for(int i = 1;i <= n;++i){
        a[i] = read();
        if(!fir[a[i]]) fir[a[i]] = i;
        las[a[i]] = i;
        sum[a[i]]++;
    }
    for(int i = 1;i <= 200000;++i){
        if(!fir[i]) continue;
        if(!las[i]) G.push_back((node){fir[i],fir[i],i});
        else G.push_back((node){fir[i],las[i],i});
    }
    sort(G.begin(),G.end(),cmp);
    int ans = 0;
    int now = 0;
    int nowr = -1;
    int len = 0;
    int from = 1;
    int maxx = 0;
 // for(int i = 0;i < (int)G.size();++i){
 //     printf("%d %d %d\n",G[i].id,G[i].li,G[i].ri);   
 // }
    while(now < G.size()){
        if(G[now].li > nowr){
            ans += nowr - from + 1 - maxx; 
            from = nowr + 1;
            maxx = 0;
            maxx = max(maxx,sum[G[now].id]);
            nowr = G[now].ri;
        }
        else{
            nowr = max(nowr,G[now].ri);
            maxx = max(maxx,sum[G[now].id]);
        }
        now++;
    }
    ans += nowr - from + 1 - maxx; 
    printf("%d\n",ans);
    return 0;
}
 

Guess you like

Origin www.cnblogs.com/wyxdrqc/p/11545310.html