Google Kick Start 2020 Ronda Un

Asignación

El significado de los problemas

N una casa en venta, vender cada Ai cuchillo, las existentes B fondos cuchillo que buscan comprar el número máximo.

pensamiento

Después de codiciosos, ordenados de menor a mayor compra

código

#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5+5;

int a[MAX];

int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        int n,b,res=0;
        scanf("%d%d",&n,&b);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        for(int i=0;i<n;i++)
        {
            if(a[i]>b)break;
            b-=a[i];
            res++;
        }
        printf("Case #%d: %d\n",++cas,res);
    }
}

Platos

El significado de los problemas

Hay n pila de platos, cada uno tiene pila k , uno para cada plato tiene un cierto valor, ahora elegir pág una placa, requiriendo sólo se puede elegir una parte de una pila de arriba a abajo, encontrar la forma de elegir el valor total de la máxima

pensamiento

El DP , DP [i] [j] denota el frente i Bundle CCP seleccionado de entre el j ésimo valor máximo disponible, el haz de corriente de transferencia se selecciona de entre la enumeración m número (opción prefijo), y la dp [i-1] [jm ] transferido desde

código

#include<bits/stdc++.h>
using namespace std;
const int MAX=1505;

int a[MAX][MAX],pre[MAX][MAX],dp[MAX][MAX];

int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        int n,p,m;
        scanf("%d%d%d",&n,&m,&p);
        memset(dp,0,sizeof dp);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
            {
                scanf("%d",&a[i][j]);
                pre[i][j]=pre[i][j-1]+a[i][j];
            }
        for(int i=1; i<=n; i++)
            for(int j=0; j<=min(i*m,p); j++)
                for(int k=0; k<=min(j,m);k++)
                    dp[i][j]=max(dp[i][j],dp[i-1][j-k]+pre[i][k]);
        printf("Case #%d: %d\n",++cas,dp[n][p]);
    }
}

Rutina de ejercicio

El significado de los problemas

Para una secuencia monótona creciente, hay n número, siempre D valor para este número de secuencia de cada diferencia entre el número máximo de adyacente, ahora pueden ser insertados en la secuencia de cualquier tamaño en cualquier posición en el caso de una secuencia monótona creciente para asegurar k número, cómo encontrar la secuencia que D es el valor más pequeño de mínimo D de valor.

pensamiento

Ocurrirán fácilmente, se puede insertar en el medio de dos números un número, por lo que tanto la diferencia original se convierte en un medio de un (redondeando hacia arriba), la primera diferencia procesar toda la secuencia original, y luego la mitad de la respuesta, entonces esto es detectado por las conclusiones anteriores la respuesta es factible, y, finalmente, llegar al mínimo.

código

#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5+5;

int n,k,a[MAX],ch[MAX];

bool check(int x)
{
    int tot=k;
    for(int i=1; i<n; i++)
    {
        if(ch[i]<=x)continue;
        for(int j=1;; j++)
        {
            int cur=(ch[i]+j)/(j+1);
            if(cur<=x)
            {
                if(j<=tot)tot-=j;
                else return 0;
                break;
            }
        }
    }
    return 1;
}

int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        int L=1,R=-1,res;
        scanf("%d%d",&n,&k);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        for(int i=1; i<n; i++)
            ch[i]=a[i]-a[i-1],R=max(R,ch[i]);
        while(L<=R)
        {
            int mid=(L+R)>>1;
            if(check(mid))
            {
                res=mid;
                R=mid-1;
            }
            else
                L=mid+1;
        }
        printf("Case #%d: %d\n",++cas,res);
    }
}

agrupación

El significado de los problemas

Para n cuerdas, en tamaño requerido k varios grupos ( n es un k múltiplo de), calificaciones de la longitud del prefijo común más larga de todas las cadenas de cada grupo. Cómo poner el marcador buscan maximizar, para obtener la máxima puntuación.

pensamiento

Al parecer prefijo común, siempre que sea posible, tan codiciosos, buscando el prefijo común más larga se puede dividir en un grupo se dividió en un grupo, para construir un árbol de diccionario, registrar el número de cadenas que comiencen con un determinado prefijo. A continuación, busque el trie en cuanto a la suficiente codiciosos en un conjunto de prefijos (es decir, para encontrar este número con la cadena de prefijo no es menos de lo k prefijo), la actualización respuesta profundidad, y luego devuelve el número se ha utilizado para padre, actualizando el número de su padre.

código

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e6+6;
typedef long long ll;

int nxt[MAX][26],sum[MAX],cnt,n,k;
ll res;
char ss[MAX];

void ins(char *s)
{
    int p=0,len=strlen(s);
    sum[p]++;
    for (int i=0; i<len; i++)
    {
        int c=s[i]-'A';
        if(!nxt[p][c])nxt[p][c]=++cnt;
        p=nxt[p][c];
        sum[p]++;
    }
}
int dfs(int x,int d)
{
    int ssum=0,cur=0;
    for(int i=0;i<26;i++)
        if(nxt[x][i])
            ssum+=dfs(nxt[x][i],d+1);
    sum[x]-=ssum;
    if(sum[x]>=k)
    {
        cur=sum[x]/k;
        res+=d*cur;
        sum[x]%=k;
    }
    return ssum+cur*k;
}
void init()
{
    memset(nxt,0,sizeof nxt);
    memset(sum,0,sizeof sum);
    cnt=0;
    res=0;
}

int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        init();
        for(int i=0;i<n;i++)
        {
            scanf("%s",ss);
            ins(ss);
        }
        dfs(0,0);
        printf("Case #%d: %lld\n",++cas,res);
    }
}

Supongo que te gusta

Origin www.cnblogs.com/cryingrain/p/12569372.html
Recomendado
Clasificación