1. 程式人生 > >Codeforces Round #340 (Div. 2) (629A,629B,629C(排列組合,動態規劃),629D(線段樹))

Codeforces Round #340 (Div. 2) (629A,629B,629C(排列組合,動態規劃),629D(線段樹))

Far Relative’s Birthday Cake

題目連結:

解題思路:

Consider that we have rowi chocolates in the i'th row and coli chocolates in the i'th column.

The answer to the problem would be: . It is obvious that every pair would be calculated exactly once (as we have no more than one chocolate in the same square)

Time Complexity: O(n2)

AC程式碼:

#include <bits/stdc++.h>
using namespace std;

char a[110][110];

int main(){
    int n;
    while(~scanf("%d",&n)){
        int ans = 0,tmp;
        for(int i = 0; i < n; i++){
            scanf("%s",a[i]);
            tmp = 0;
            for(int j = 0; j < n; j++){
                if(a[i][j] == 'C')
                    tmp++;
            }
            ans += tmp*(tmp-1)/2;
        }
        for(int i = 0; i < n; i++){
            tmp = 0;
            for(int j = 0; j < n; j++){
                if(a[j][i] == 'C')
                    tmp++;
            }
            ans += tmp*(tmp-1)/2;
        }
        printf("%d\n",ans);
    }
    return 0;
}

Far Relative’s Problem

題目連結:

解題思路:

Consider that we have boyi males in the i'th day of the year and girli females in the i'th day of the year. These arrays can be filled easily when you are reading the input (See the code). Then for the i'th day of the year, we could have 2 * min(boyi , girl

i) people which could come to the party. The answer would be maximum of this value between all days i (1 ≤ i ≤ 366)

Time Complexity: O(366*n)

AC程式碼:

#include <bits/stdc++.h>
using namespace std;

struct node{
    char sex[10];
    int a,b;
}no[5005];

int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i = 0; i < n; i++)
            scanf("%s%d%d",no[i].sex,&no[i].a,&no[i].b);
        int ans = 0,M,F;
        for(int i = 1; i <= 366; i++){
            M = 0;F = 0;
            for(int j = 0; j < n; j++){
                if(no[j].a <= i && no[j].b >= i){
                    if(no[j].sex[0] == 'M')
                        M++;
                    else
                        F++;
                }
            }
            ans = max(ans,min(M,F));
        }
        printf("%d\n",ans*2);
    }
    return 0;
}

Famil Door and Brackets

題目連結:

解題思路:

This problem can be solved with dynamic programming:

1. Calculate dpi, j : How many sequences of brackets of length i has balance j and intermediate balance never goes below zero (They form a prefix of a valid sequence of brackets).

2. For the given sequence of length n calculate the resulting balance a and the minimum balance b.

3. Try the length of the sequence added at the beginning c and its balance d. If  - b ≤ d then add dpc, d * dm - n - c, d + a to the answer.

Time complexity: O((n - m)^2)

AC程式碼:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int MOD = 1e9+7;
ll dp[5005][5005];


int main(){
    ll n,m;
    while(~scanf("%lld%lld",&n,&m)){
        string str;
        cin>>str;
        dp[0][0] = 1;
        for(int i = 1; i <= n-m; i++){
            dp[i][0] = dp[i-1][1];
            for(int j = 1; j <= i; j++){
                dp[i][j] = dp[i-1][j+1]+dp[i-1][j-1];
                dp[i][j] %= MOD;
            }
        }
        int num = 0,minnum = 0;
        for(int i = 0; i < m; i++){
            if(str[i] == '(')
                num++;
            else
                num--;
            minnum = min(minnum,num);
        }
        ll ans = 0;
        for(int i = 0; i <= n-m; i++){
            for(int j = 0; j <= i; j++){
                if(j >= -minnum){
                    if(j+num <= n-m && j+num >= 0){
                        ans += dp[i][j] * dp[n - m - i][j + num] % MOD;
                        ans %= MOD;
                    }
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

Babaei and Birthday Cake

題目連結:

解題思路:

First of all, we calculate the volume of each cake: vi = π × hi × ri2.

Now consider the sequence v1v2v3, ..., vn : The answer to the problem is the maximum sum of elements between all increasing sub-sequences of this sequence. How do we solve this? First to get rid of the decimals we can define a new sequence a1a2a3, ..., an such that 

We consider dpi as the maximum sum between all the sequences which end with ai and

dpi = 

The answer to the problem is: π × maxi = 1ndp[i]

Now how do we calculate  ? We use a max-segment tree which does these two operations: 1. Change the i't member to v2. Find the maximum value in the interval 1 to i.

Now we use this segment tree for the array dp and find the answer.

Consider that a1a2a3, ..., an is sorted. We define bi as the position of ai. Now to fill dpi we find the maximum in the interval [1, bi) in segment and we call it x and we set the bi th index of the segment as ai + x. The answer to the problem would the maximum in the segment in the interval [1,n]

Time complexity: O(nlgn)

AC程式碼:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 100005;
const double pi = acos(-1.0);

struct node{
    ll r, h, v;
}no[maxn];
struct node2{
    int l,r;
    ll maxv;
}tree[maxn<<2];
int n,m;
ll d[maxn],b[maxn];

void pushup(int id) {
    tree[id].maxv = max(tree[id<<1].maxv,tree[id<<1|1].maxv);
}

void build(int id,int l,int r){
    tree[id].l = l;
    tree[id].r = r;
    tree[id].maxv = 0;
    if(l == r)
        return ;
    int m = (l + r) >> 1;
    build(id<<1,l,m);
    build(id<<1|1,m+1,r);
}

void update(int id,int l,int r,int val){
    if(tree[id].l >= l && tree[id].r <= r){
        if(tree[id].maxv < d[val]){
            tree[id].maxv = d[val];
        }
        return ;
    }
    int mid = (tree[id].l+tree[id].r)>>1;
    if(l <= mid)
        update(id<<1,l,r,val);
    if(mid < r)
        update(id<<1|1,l,r,val);
    pushup(id);
}

ll query(int id,int l,int r) {
    if(tree[id].l >= l && tree[id].r <= r)
        return tree[id].maxv;
    ll ans = 0;
    int mid = (tree[id].l+tree[id].r)>>1;
    if(l <= mid)
        ans = max(ans, query(id<<1,l,r));
    if(mid< r)
        ans = max(ans, query(id<<1|1,l,r));
    pushup(id);
    return ans;
}

int main(){
    while(~scanf("%d",&n)){
        for(int i = 1; i <= n; i++){
            scanf("%lld%lld",&no[i].r,&no[i].h);
            no[i].v = no[i].r * no[i].r * no[i].h;
            b[i] = no[i].v;
        }
        sort(b+1, b+1+n);
        int m = unique(b+1, b+1+n) - b - 1;

        ll cur = 0,v;
        build(1,1,m);
        for(int i = 1; i <= n; i++) {
            int L = lower_bound(b+1, b+1+m, no[i].v) - b;
                if(L > 1) v = query(1,1,L-1);
                else v = 0;
                d[i] = (v + no[i].v);
                update(1,L,L,i);
                cur = max(cur, d[i]);
        }
        printf("%.9f\n",pi*cur);
    }
    return 0;
}