Cod sursa(job #2972549)

Utilizator Bogdan345Marius Mihalache Bogdan345 Data 29 ianuarie 2023 18:18:59
Problema Cel mai lung subsir comun Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 14.94 kb
/*
#include <vector>
#include <iostream>
#include <climits>
#include <algorithm>
using namespace std;
vector<int>nr,dp,inainte;
//dp-ul este lungimea celui mai mare
//subsir de pe pozitia i,elementul i fiind
//capatul subsirului
int main(){
    int n;
    cin>>n;
    nr.resize(n+1);
    dp.resize(n+1);
    inainte.resize(n+1);
    dp[0]=0;
    nr[0]=0;
    for(int i=1;i<=n;i++){
        cin>>nr[i];
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<n;j++){
            if(nr[j]<nr[i]){
                if(dp[j]+1>dp[i]){
                    dp[i]=dp[j]+1;
                    inainte[i]=j;
                }
            }
        }
    }
    /*
--Metoda I-de afisare
    int max1=INT_MIN;
int acum=dp[0];
for(int i=1;i<=n;i++){
if(dp[i]>dp[acum]){
    acum=i;
}
}
vector<int>raspuns;
while(acum>0){
   raspuns.push_back(nr[acum]);
   acum=deUndeVin[acum];
}
cout<<raspuns.size()<<'\n';
reverse(raspuns.begin(),raspuns.end());
for(auto&x:raspuns){
    cout<<x<<" ";
}
----Metoda II -de afisare
int max1=INT_MIN;
int acum;
for(int i=1;i<=n;i++){
   max1=max(max1,dp[i]);
   acum=i;
}
cout<<max1<<'\n';
vector<int>raspuns;
while(acum>1){
    raspuns.push_back(nr[acum]);
    acum=inainte[acum];
}
reverse(raspuns.begin(),raspuns.end());
for(auto&x:raspuns){
    cout<<x<<" ";
}
}
*/
/*
#include <fstream>
#include <iostream>
#include <climits>
#include <algorithm>
using namespace std;
ifstream cin("plopi1.in");
ofstream cout("plopi1.out");
vector<int>nr,dp,inainte;
//dp-ul este lungimea celui mai mare
//subsir de pe pozitia i
//Plopi1-O(n)
//dau reverse la sirul de numere
//pentru a calcula lungimea celui
//mai mare sir crescator care
//este pentru sirul anterior de fapt
//descrescator
int main(){
    int n;
    cin>>n;
    nr.resize(n+1);
    dp.resize(n+1);
    for(int i=1;i<=n;i++){
        cin>>nr[i];
    }
    reverse(nr.begin(),nr.end());
    dp[0]=0;
    nr[0]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<n;j++){
            if(nr[j]<nr[i]){
                if(dp[j]+1>dp[i]){
                    dp[i]=dp[j]+1;
                }
            }
        }
    }
    int max1=INT_MIN;
    for(int i=1;i<=n;i++){
        max1=max(max1,dp[i]);
    }
cout<<n-max1;

}

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
vector<int>dp,nr;
vector<int>deUndeVin;
int const inf=2e9+1;
//imi retin pozitia celui mai mic capat
//al unui subsir de lungime i
//caut binar cel mai lung subsir de lungime i
//la care pot sa ma lipesc
int pozitiaCeluiMaiMicCapatAlSiruluiI(int i){
    int st=0;
    int dr=i-1;
    int rasp=0;
    while(st<=dr){
        int mij=(st+dr)/2;
        if(nr[i]>nr[dp[mij]]){
            rasp=mij;
            st=mij+1;
        }else{
        dr=mij-1;
        }
    }
return rasp;
}
int main(){
    int n;
    cin>>n;
    dp.resize(n+2);
    nr.resize(n+2);
    deUndeVin.resize(n+2);
    for(int i=1;i<=n;i++){
        cin>>nr[i];
        dp[i]=n+1;
    }

nr[n+1]=inf;
int max1=0;
int ans;
for(int i=1;i<=n;i++){
 ans=pozitiaCeluiMaiMicCapatAlSiruluiI(i);
 dp[ans+1]=i;
 deUndeVin[i]=dp[ans];
 max1=max(max1,ans+1);
}
cout<<max1<<'\n';
int acum=dp[max1];
vector<int>rasp;
while(acum){
   rasp.push_back(nr[acum]);
   acum=deUndeVin[acum];
}
reverse(rasp.begin(),rasp.end());
for(auto&x:rasp){
    cout<<x<<" ";
}
}
-------
//Baloane
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
vector<int>dp,nr;
int const inf=2e9+1;
//imi retin pozitia celui mai mic capat
//al unui subsir de lungime i
//caut binar cel mai lung subsir de lungime i
//la care pot sa ma lipesc
int pozitiaCeluiMaiMicCapatAlSiruluiI(int i){
    int st=0;
    int dr=i-1;
    int rasp=0;
    while(st<=dr){
        int mij=(st+dr)/2;
        if(nr[i]>nr[dp[mij]]){
            rasp=mij;
            st=mij+1;
        }else{
        dr=mij-1;
        }
    }
return rasp;
}
int main(){
    int n;
    cin>>n;
    dp.resize(n+2);
    nr.resize(n+2);
    deUndeVin.resize(n+2);
    for(int i=1;i<=n;i++){
        cin>>nr[i];
        dp[i]=n+1;
    }
reverse(nr.begin(),nr.end());
nr[n+1]=inf;
int max1=0;
int ans;
for(int i=1;i<=n;i++){
 ans=pozitiaCeluiMaiMicCapatAlSiruluiI(i);
 dp[ans+1]=i;
 max1=max(max1,ans+1);
}
cout<<n-max1;

}
*/
//Radiera
//Metoda I-O(n^2)
/*
#include <fstream>
#include <vector>
#include <climits>
using namespace std;
vector<int>dp,nr;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    dp.resize(n+1);
    nr.resize(n+1);
    for(int i=1;i<=n;i++){
        cin>>nr[i];
    }
    dp[0]=0;
    nr[0]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<i;j++){
            if(nr[i]>=nr[j]){
                if(dp[j]+1>dp[i]){
                    dp[i]=dp[j]+1;
                }
            }
        }
    }
    int max1=INT_MIN;
    for(int i=1;i<=n;i++){
        max1=max(max1,dp[i]);
    }
cout<<n-max1;
}

//Metoda II-O(n*logn)
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
vector<int>nr,dp;
int cautBinPoz(int i){
int st=0;
int dr=i-1;
int rasp=0;
while(st<=dr){
    int mij=(st+dr)/2;
    if(nr[i]>=nr[dp[mij]]){
        rasp=mij;
        st=mij+1;
    }else{
    dr=mij-1;
    }
}
return rasp;

}
const int inf=2e9+1;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    dp.resize(n+2);
    nr.resize(n+2);
    for(int i=1;i<=n;i++){
        cin>>nr[i];
        dp[i]=n+1;
    }
nr[n+1]=inf;
int ans;
int max1=INT_MIN;
for(int i=1;i<=n;i++){
   ans=cautBinPoz(i);
   dp[ans+1]=i;
   max1=max(max1,ans+1);
}
cout<<max1;
}

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
vector<vector<long long>>nr,dp;
const int inf=1e9+1;
int cautBin(int i,int j){
    int st=0;
    int dr=j-1;
    int rasp=0;
    while(st<=dr){
        int mij=(st+dr)/2;
        if(nr[i][j]>=nr[i][dp[i][mij]]){
            rasp=mij;
            st=mij+1;
        }else{
        dr=mij-1;
        }
    }
return rasp;
    }
//Joc 6
int main(){
int n;
int S1=0;
int S2=0;
cin>>n;
nr.resize(n+2,vector<long long >(n+2));
dp.resize(n+2,vector<long long>(n+2));
for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>nr[i][j];
            dp[i][j]=n+1;
        }
}
for(int i=1;i<=n;i++){
    nr[i][n+1]=inf;
}
for(int i=1;i<=n;i++){
    if(i%2){
    int ans1;
    int max1=-1;
        for(int j=1;j=n;j++){
            ans1=cautBin(i,j);
    dp[i][ans1+1]=j;
    max1=max(max1,ans1+1);
        }
    S1+=max1;
    }else{
        int ans;
        reverse(nr[i].begin(),nr[i].end());
        nr[i][n+1]=inf;
    int max2=-1;
        for(int j=1;j=n;j++){
            ans=cautBin(i,j);
    dp[i][ans+1]=j;
    max2=max(max2,ans+1);
        }
    S2+=max2;

    }
}
cout<<S1<<" "<<S2;
}
-----
//SCLMprime
#include <iostream>
#include <vector>
using namespace std;
vector<int>nr,dp,inainte;
const long long inf= 1000000+2;
bool estePrim(int n){
    int div=2;
    while(div*div<=n){
        if(n%div==0){
         return false;
        }
    div++;
    }
return true;
}
int cautBin(int i){
int st=0;
int dr=i-1;
int rasp=0;
while(st<=dr){
    int mij=(st+dr)/2;
    if(nr[i]>nr[dp[mij]]){
        if(estePrim(nr[dp[mij]])){
        rasp=mij;
        }
        st=mij+1;
    }else{
    dr=mij-1;
    }
}

}
int main(){
int n;
cin>>n;
nr.resize(n+2);
dp.resize(n+2);
inainte.resize(n+2);
for(int i=1;i<=n;i++){
    cin>>nr[i];
    dp[i]=n+1;
}
nr[n+1]=inf;
int ans;
int max1=-1;
for(int i=1;i<=n;i++){
    if(estePrim(nr[i])){
    cout<<nr[i]<<'\n';
    ans=cautBin(i);
    dp[ans+1]=i;
    inainte[i]=dp[ans];
    max1=max(max1,ans+1);
}
}
cout<<max1<<'\n';

vector<int>rasp;
int acum=dp[max1];
while(acum>0){
    rasp.push_back(nr[acum]);
    acum=inainte[acum];
}
for(auto&x:rasp){
    cout<<x<<" ";
}

}

//Up
#include <fstream>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;
ifstream cin("up.in");
ofstream cout("up.out");
vector<int>dp,nr,inainte;
const int inf=INT_MAX;
int cautBin(int i){
int st=0;
int dr=i-1;
int ans=0;
while(st<=dr){
    int mij=(st+dr)/2;
    if(nr[i]>nr[dp[mij]]){
        ans=mij;
        st=mij+1;
    }else{
        dr=mij-1;
    }
}
return ans;
}
int main(){
    int n;
    cin>>n;
    dp.resize(n+2);
    nr.resize(n+2);
    inainte.resize(n+2);
    for(int i=1;i<=n;i++){
        cin>>nr[i];
        dp[i]=n+1;
    }
    nr[n+1]=inf;
    int max1=-inf;
    for(int i=1;i<=n;i++){
      int rasp=cautBin(i);
      dp[rasp+1]=i;
      inainte[i]=dp[rasp];
      max1=max(max1,rasp+1);
    }
cout<<max1<<'\n';

}

//Cmlsc
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
#include <algorithm>

using namespace std;



vector<int> a, b;
vector<vector<int>> dp; // dp[i][j] = lungimea maxima a unui subsir comun pana la poz i in A si poz j in B

void afisare(int i, int j) {

    // eu sunt la dp[i][j] -> de unde am venit?
    // daca dp[i][j] == dp[i-1][j-1] + 1 si A[i] == B[j] -> A[i] face parte din solutie si eu vin din dp[i-1][j-1]
    // daca dp[i][j] == dp[i-1][j] -> vin din acest dp
    // daca dp[i][j] == dp[i][j-1] -> vin din acest dp

    if (i < 1 || j < 1) { // stare de start -> ma opresc
        return;
    }
    if (dp[i][j] == dp[i-1][j-1] + 1 && a[i] == b[j]) {
        afisare(i - 1, j - 1);
        cout << a[i] << " "; // afisez atunci cand ma intorc
        return;
    }
    if (dp[i][j] == dp[i-1][j]) { // ignor pozitia i
        afisare(i - 1, j);
        return;
    }
    if (dp[i][j] == dp[i][j-1]) { // ignor pozitia j
        afisare(i, j - 1);
        return;
    }
}

int main(){

    int n, m;
    cin>>n>>m;

    a.resize(n+1);
    b.resize(m+1);
    dp.resize(n+1, vector<int>(m+1, 0));

    for (int i=1; i<=n; i++){
        cin>>a[i];
    }
    for (int i=1; i<=m; i++){
        cin>>b[i];
    }

    // starea initiala dp[i][0] = 0 si dp[0][j] = 0 (nu trebuie sa le mai dam valori pentru ca tot dp-ul este 0 din start)

    for (int i=1; i<=n; i++){
        for (int j=1; j<=m; j++){
            // recurenta in spate
            dp[i][j] = max(dp[i-1][j-1] + (a[i] == b[j]) , max(dp[i-1][j] , dp[i][j-1]));
        }
    }


    /*
    dp[1][1] = 0
    A = 1
    B = 7

    dp[1][3] = 0
    A = 1
    B = 7 5 8

    dp[2][3] = 1
    A = 1 7
    B = 7 5 8

    for (int i=1; i<=n; i++){
        for (int j=1; j<=m; j++){
            cout<<dp[i][j]<<" ";
        }
        cout<<'\n';
    }


    // starea finala dp[n][m]
    cout<<dp[n][m]<<'\n';

    // afisare
    afisare(n, m);
}

#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("joc6.in");
ofstream cout("joc6.out");
vector<vector<int>>nr;
vector<int>dp;
const int inf=1e9;
int cautBin(int i,int j){
    int st=0;
    int dr=j-1;
    int rasp=0;
    while(st<=dr){
        int mij=(st+dr)/2;
        if(nr[i][j]>=nr[i][dp[mij]]){
           rasp=mij;
           st=mij+1;
        }else{
        dr=mij-1;
        }
    }
return rasp;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
int n;
cin>>n;
nr.resize(n+2,vector<int>(n+2));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
    cin>>nr[i][j];

}
}


int max1;
int max2;
int S1=0;
int S2=0;
for(int i=1;i<=n;i++){
    if(i%2){
    max1=-1;
    dp.resize(n+2,n+1);
    nr[i][n+1]=inf;
     dp[0]=0;
     int ans;
     for(int j=1;j<=n;j++){
        ans=cautBin(i,j);
        dp[ans+1]=j;
        max1=max(max1,ans+1);
     }
    S1+=max1;
     dp.clear();
    }else{
        max2=-1;
    reverse(nr[i].begin()+1,nr[i].begin()+n+1);
    dp.resize(n+2,n+1);
      nr[i][n+1]=inf;
     dp[0]=0;
     int ans;
     for(int j=1;j<=n;j++){
        ans=cautBin(i,j);
        dp[ans+1]=j;
        max2=max(max2,ans+1);
     }
    S2+=max2;
    dp.clear();
    }
}
cout<<S1<<" "<<S2<<'\n';
if(S1>S2){
    cout<<"UNU";
}else if(S1==S2){
cout<<"REMIZA";
}else{
    cout<<"DOI";
}

}

#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("sclmprime.in"); ofstream cout("sclmprime.out");
vector<int>dp,nr,inainte;
vector<bool>folosit;
const int inf=1e7+1;
bool nrPrim(int n){//Metoda I-O(n*radical(n)*logn)
if(n<2){
    return false;
}
int div=2;
while(div*div<=n){
    if(n%div==0){
        return false;
    }
div++;
}
return true;
}
const int a=1e7+1;
void ciur(){
      folosit.resize(a+1,true);
      folosit[1]=folosit[0]=false;
    for(int i=2;i<=a;i++){
        if(folosit[i]){
        for(int j=i+i;j<=a;j+=i){
            folosit[j]=false;
        }

        }
    }

}
int cautBin(int i){
    int st=0;
    int dr=i-1;
    int rasp=0;
    while(st<=dr){
        int mij=(st+dr)/2;
        if(nr[i]>=nr[dp[mij]]){
            rasp=mij;
            st=mij+1;
        }else{
        dr=mij-1;
        }
    }
return rasp;
}
int main(){
    ciur();
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    nr.resize(n+2);
    dp.resize(n+2);
    inainte.resize(n+2);
    for(int i=1;i<=n;i++){
        cin>>nr[i];
        dp[i]=n+1;
    }
    nr[n+1]=inf;
    int ans;
    int max1=-1;
    for(int i=1;i<=n;i++){
        //if(nrPrim(nr[i])){
        if(folosit[nr[i]]){
        ans=cautBin(i);
        dp[ans+1]=i;
        inainte[i]=dp[ans];
        max1=max(max1,ans+1);
        }
        //}
    }
    int acum=dp[max1];
    vector<int>sir;
    while(acum){
        sir.push_back(nr[acum]);
        acum=inainte[acum];
    }
    cout<<max1<<'\n';
    reverse(sir.begin(),sir.end());
    for(auto&x:sir){
        cout<<x<<" ";
    }
}
*/
#include <fstream>
#include <vector>
//subsir comun pana in i si in j
//fixez litera i si parcurg
//de fiecare date toate litere sirului
//j deoarece imi caut litera comuna cu litera i
//imi actualizez starile si imi retin pentru fiecare
//pozitie lungimea sirului gasit
using namespace std;
ifstream cin("cmlsc.in");
ofstream cout("cmlsc.out");
vector<int>A,B;
vector<vector<int>>dp;
void afisare(int i,int j){
if(i<1 || j<1){
    return;
}
if(dp[i][j]==dp[i-1][j-1]+1 && A[i]==B[j]){
    afisare(i-1,j-1);
    cout<<A[i]<<" ";
    return;
}else if(dp[i][j]==dp[i][j-1]){
    afisare(i,j-1);
    return;
}else if(dp[i][j]==dp[i-1][j]){
afisare(i-1,j);
return;
}
}
int main(){
int a,b;
cin>>a>>b;
A.resize(a+1);
B.resize(b+1);
for(int i=1;i<=a;i++){
cin>>A[i];
}
for(int j=1;j<=b;j++){
cin>>B[j];
}
dp.resize(a+1,vector<int>(b+1));
for(int i=1;i<=a;i++){//Complexitate:O(a*b)
    for(int j=1;j<=b;j++){
       dp[i][j]=max(max(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1]+(A[i]==B[j]));
    }
}
cout<<dp[a][b]<<'\n';
afisare(a,b);
}