Tres preguntas

O póngalo en orden de dificultad creciente.

T1 https://www.luogu.com.cn/problem/P3360

Dado que el orden que da es un orden dfs, entonces lee directamente mientras dfs está terminado, porque tiene tanto volumen como valor, por lo que es suficiente para enumerar cuánto tiempo se asigna a cada corredor, que es un problema de mochila en un árbol.

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=600;
ll dp[N][N],v;
int n,w,cnt;
void dfs(int u){
    int t,x;
    scanf("%d%d",&t,&x);
    t<<=1;
    if(x){
        for(int i=1;i<=x;i++){
            scanf("%lld%d",&v,&w);
            for(int j=n;j>=t+w;j--){
                dp[u][j]=max(dp[u][j],dp[u][j-w]+v);
            }
        }
        return ;
    }
    int l=++cnt;dfs(l);
    int r=++cnt;dfs(r);
    for(int i=t;i<=n;i++)
        for(int j=0;i>=j+t;j++)
            dp[u][i]=max(dp[u][i],dp[l][j]+dp[r][i-j-t]);
}
int main(){
    scanf("%d",&n);
    n--;
    cnt=1;
    dfs(1);
    printf("%lld\n",dp[1][n]);
}

T2 https://www.luogu.com.cn/problem/P4303

Esta pregunta es bastante simple. Si no observa el rango de datos, simplemente ejecute un LCS. Pero su rango de datos es muy grande, por lo que debe considerar el método de escritura NlogN de LCS. Obviamente no es posible configurar directamente el tablero, porque hay repeticiones, y el número de repeticiones es el mismo, es decir, solo hay 5 posiciones en otra secuencia. La longitud del LCS se actualiza, así que grabo estas 5 posiciones y las escribo de acuerdo con el método NlogN, y luego enumero e intento actualizar las respuestas una por una. Pero hay un problema, si las cinco posiciones son 1, 2, 3, 4, 5 por turno, entonces esto puede actualizarse con una actualización, ¿no ha terminado? Entonces, para evitar que esto suceda, debe enumerar al revés.

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int w,n;
int tr[N];
int lowbit(int i){
    return i&-i;
}
void updata(int x,int val){
    while(x<=n){
        tr[x]=max(tr[x],val);
        x+=lowbit(x);
    }
}
int find(int x){
    int res=0;
    while(x){
        res=max(res,tr[x]);
        x-=lowbit(x);
    }
    return res;
}
int main(){
    vector<int > pos[N];
    scanf("%d",&n);
    n*=5;
    for(int i=1;i<=n;i++){
        scanf("%d",&w);
        pos[w].push_back(i);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&w);
        for(int j=pos[w].size()-1;j>=0;j--)
            updata(pos[w][j],find(pos[w][j]-1)+1);
    }
    printf("%d\n",find(n));
}

T3


A primera vista, esta pregunta no tiene idea, excepto, por supuesto, para el reloj. Entonces solo puedes mirar.
Lo primero que encontré en el reloj es que la respuesta a la primera pregunta fue n-2 y algunos juicios especiales, así que printf n-2, 20 puntos.
No quería demostrarlo en ese momento, pero ahora tengo que demostrarlo.
El caso donde el número máximo de soluciones es n obviamente no existe, y definitivamente se incluirá. ¿Qué pasa con n-1? El esquema de 1 debe ser n y la unión de n-1 debe ser n, y el esquema de 2 no debe contener 1, entonces, ¿cómo se puede generar este esquema 2, es así, por lo que solo puede ser n-2?
De hecho, esta prueba no es muy rigurosa, solo entiéndelo.
Así que consideremos generar estos esquemas n-2. La tabla definitivamente se puede imprimir, pero cuando se juega ............... No, entonces no hay forma de hacer un esquema fácilmente ¿Qué hay de generar otra solución? Por ejemplo, lo siguiente:
\ (x_1 \)
\ (x_2 \) \ (x_3 \)
\ (x_3 \) \ (x_4 \) \ (x_5 \)
Considerando cómo se puede obtener el siguiente esquema, obviamente puedo Agregue un número al reverso y luego empuje cada línea hacia atrás, la primera línea está vacante y otro número es suficiente. Ponga 1 a n-2 en la última línea, la generación se completa, por lo que esta pregunta se convierte en una pregunta de simulación mágica, y luego presione A. . . . .
Todavía hay un problema, este método de generación solo se puede pasar de n-2 a n, por lo que es necesario considerar si el número dado es par o impar.

#include<cstdio>
using namespace std;
const int N=1e3+10;
int num[N][N];
int main(){
//    freopen("course.in","r",stdin);
//    freopen("course.out","w",stdout);
    int n;
    scanf("%d",&n);
    if(n==1||n==2){
        printf("1\n1 1");
    }
    else if(n==3){
        printf("2\n1 1\n2 2 3");
    }
    else {
        printf("%d\n",n-2);
        num[1][1]=1;num[2][1]=2;num[2][2]=3;
        if(n&1){
            for(int i=5;i<=n;i+=2){
                for(int j=1;j<=i-4;j++)
                    num[j][j+1]=i;
                for(int j=i-4;j>=1;j--)
                    for(int k=1;k<=j+1;k++)
                        num[j+1][k]=num[j][k];
                num[1][1]=i-1;
                for(int j=1;j<=i-2;j++)
                    num[i-2][j]=j;
            }
            for(int i=1;i<=n-2;i++){
                printf("%d ",i);
                for(int j=1;j<=i;j++)printf("%d ",num[i][j]);
                printf("\n");
            }
        }
        else{
            for(int i=6;i<=n;i+=2){
                for(int j=1;j<=i-4;j++)
                    num[j][j+1]=i;
                for(int j=i-4;j>=1;j--)
                    for(int k=1;k<=j+1;k++)
                        num[j+1][k]=num[j][k];
                num[1][1]=i-1;
                for(int j=1;j<=i-2;j++)
                    num[i-2][j]=j;
            }
            for(int i=1;i<=n-2;i++){
                printf("%d ",i);
                for(int j=1;j<=i;j++)printf("%d ",num[i][j]);
                printf("\n");
            }
        }
        /*else if(n==4){
            printf("2\n1 1\n2 2 3");
        }
        else if(n==6){
            printf("4\n1 1\n2 2 3\n3 2 4 5\n4 4 5 6");
        }*/
    }
}

Supongo que te gusta

Origin www.cnblogs.com/anyixing-fly/p/12755411.html
Recomendado
Clasificación