17蓝桥杯决赛 对局匹配

dp问题

先转换为权值数据,把权值数据化为K组(K1,K2……)数据
每一组数据相当于k等于1的子问题。 
最后将最后k个加起来就是答案。
比如说样例
21 2
1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6
转化为权值数据为1 2 3 4 5 6
分成两组
1 3 5  k1
2 4 6  k2
k1子问题的答案是1+5=6
k2子问题的答案是2+6=8

最后问题的答案就是14。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,k;
const int MAX = 100010;
int dp[MAX]={0};
int ans[MAX]={0};
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)//赋权值 
	{
		int buf;
		scanf("%d",&buf);
		ans[buf]++;
	}
	for(int i=0;i<=MAX;i++)//实际上是进行了k次dp,这里简写成一趟。 
	{
		int buf1,buf2;
		if(i-k<0)buf1=0; 
		else buf1=dp[i-k];
		
		if(i-2*k<0)buf2=0;
		else buf2=dp[i-2*k];
		
		dp[i]=max(buf1,buf2+ans[i]);//状态转移方程 
	}
	if(k==0)//特判一下k=0的情况 
	{
        int Count=0;
        for(int i=1;i<=MAX;i++)
            if(ans[i]!=0)
                Count++;
        printf("%d",Count);
    }
    else{
    	int tot=0;
		for(int i=0;i<k;i++)//将后面k个加起来就是答案 
			tot+=dp[MAX-i];
		printf("%d\n",tot);
    }
	for(int i = 0;i<100;i++)
		printf("%d ",dp[i]); 
	return 0;
}

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页