Google Kick Start 2020 Round A

Allocation

The meaning of problems

N a house for sale, sell each Ai knife, the existing B knife funds seeking to buy the maximum number.

Thinking

After greedy, sorted from small to large buy

Code

#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);
    }
}

Plates

The meaning of problems

There are n stack of plates, each have pile k , one for each dish has a certain value, now choose p a plate, requiring you can only choose a part of a stack from top to bottom, find how to choose the total value of the maximum

Thinking

The DP , DP [i] [j] denotes the front i bundle CCP selected from the j th maximum value available, the transfer current bundle is selected from the enumeration m number (prefix option), and the dp [i-1] [jm ] transferred from

Code

#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]);
    }
}

Workout

The meaning of problems

To a monotonically increasing sequence, there are n number, provided D value for this sequence number of each difference between the maximum number of adjacent, can now be inserted into the sequence of any size at any position in the case of a monotonically increasing sequence to ensure k number, how to find the sequence that D was the smallest value of minimum D value.

Thinking

Readily occur, it can be inserted in the middle of two numbers a number, so that both the original difference becomes a one half (rounded up), the first difference processing all original sequence, and then half the answer, then this is detected by the above conclusions The answer is feasible, and finally get the minimum.

Code

#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);
    }
}

Bundling

The meaning of problems

To n strings, into required size k several groups ( n is a k multiple of), scores for the length of the longest common prefix of all strings of each group. How to make the score seek to maximize, to obtain the maximum score.

Thinking

Apparently common prefix as long as possible, so greedy, looking for the longest common prefix can be divided into one group split into a group, to build a dictionary tree, record the number of strings that begin with a certain prefix. Then find the trie as far as the greedy enough into a set of prefixes (i.e., to find this number with the prefix string is not less than k prefix), then the depth update answer, and then returns the number has been used to father, updating the number of his father's.

Code

#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);
    }
}

Guess you like

Origin www.cnblogs.com/cryingrain/p/12569372.html