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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值