Blue Bridge Cup Exams - game matching (dynamic programming)

topic:

Here Insert Picture Description

input Output:

Here Insert Picture Description

analysis:

All scores can be divided into k groups, for example, if k is equal to 2, it can be divided into two groups, are {0,2,4, ... 10,000}, {1,3,5,7, ..., 9999} , then the time in the same group of people have a chance to match, between different groups of people can not be matched, and secondly, and then use an array val, to count the number of teams in each fraction appeared, so at this time, we use for each group dp, dp [i] represents the number of people in the same team before the match up to the i-th fraction less than at this time the state transition equation is:
d p [ i ] = m a x ( d p [ i 2 ] + v a l [ i ] , d p [ i 1 ] ) dp[i] = max(dp[i-2]+val[i],dp[i-1])
DP [I-2] Val + [I] represents the current selected fraction, then the time is certainly not transferred from the dp [i-1], can be transferred from dp [i-2], dp-1] represents the current score is not selected, transferred directly from dp [i-1] over, finally, since twenty-two possible matching between the k-th group, each group so only up to the number of addition can be to get the final answer. For the case where k is equal to 0 is determined separately.

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

const int MAXN = 100005;
int cnt[MAXN],dp[MAXN],val[MAXN];
//cnt[i]表示分数为i的人数 dp[i]表示当前小组下前i个分数最多同时在线寻找对手却匹配不起来的人数
int n,k,ans,ind;

int main()
{
    int score;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&score);
        cnt[score]++;
    }
    if(k == 0)
    {
        for(int i=0;i<MAXN;++i)
            if(cnt[i]) ++ans;
    }
    else
    {
        for(int i=0;i<k;++i)  //将所有的人数分为k组 k组相互之间必不可能匹配起来
        {
            ind = 0;
            for(int j=i;j<MAXN;j+=k)
                val[ind++] = cnt[j]; //val数组顺序存放第i组中每个分数的人数
            dp[0] = val[0];
            for(int j=1;j<ind;++j)
            {
                if(j==1) dp[j] = max(dp[0],val[1]);
                else
                    dp[j] = max(dp[j-2]+val[j],dp[j-1]);
                    /*val[j]只有可能与val[j-1]相匹配 所以当有两种
                     *选择,如果选择取val[j],那么就必须从上上一
                     *个跳转过来,如果不取则可能从上一个跳转过来
                     */
            }
            ans += dp[ind-1]; //由于k个小组相互之间不可能匹配 所有累加即可
        }
    }
    printf("%d\n",ans);
    return 0;
}

Published 61 original articles · won praise 7 · views 3633

Guess you like

Origin blog.csdn.net/weixin_42469716/article/details/104660318