蓝桥杯对局匹配及动态规划

题干:
问题描述
  小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。
  小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于K,系统都不会将他们匹配。
  现在小明知道这个网站总共有N名用户,以及他们的积分分别是A1, A2, … AN。
  小明想了解最多可能有多少名用户同时在线寻找对手,但是系统却一场对局都匹配不起来(任意两名用户积分差不等于K)?
输入格式
  第一行包含两个个整数N和K。
  第二行包含N个整数A1, A2, … AN。
  对于30%的数据,1 <= N <= 10
  对于100%的数据,1 <= N <= 100000, 0 <= Ai <= 100000, 0 <= K <= 100000
输出格式
  一个整数,代表答案。
样例输入
10 0
1 4 2 8 5 7 1 4 2 8
样例输出
6

在这道题目中,我们就需要运用到动态规划的知识。
在我们学习动态规划前我们或许会用bfs,dfs,递归来写这道题,但是,我们不难发现当我们使用前面三个算法的时候,我们的时间复杂度会很高。是n^n次方,当n是一个较大的值的时候,我们必然会超时,其中的原因很大是因为我们出现了重叠子问题的现象。而动态规划就能很好的规避这个问题
(动态规划入门传送门:https://blog.csdn.net/malloch/article/details/108785654)
思路
动态规划主要是来对问题的拆分,使其变成若干的子问题,再通过若干子问题的解决来实现对最初问题的解决,所以我们首先需要考虑的是对于问题的拆分,即我们如何讲我们所需要的问题拆分成若干子问题,并且将着若干子问题都使用状态转移方程式来实现链接。
在对局匹配中分数差值K是一个关键信息,在差值不为K的时候系统将不会进行匹配,所以可以将状态转移公式的变量定为K。
我们容易知道,当我所有的数值<=K的时候,我们可以将我们所拥有的积分信息进行以K为等差的分类,我们将其分为N组,在这N组中,每一组的首元素都不超过K的值(因为当我们的数组值的首元素超过了K的时候,便会出现重复的情况)。
当我们将其分为了N个数组之后,我们可以容易的知道,每一个的分组都不会于其他分组的匹配到一起,所以我们的思路就转变为单独求每一组的最大不能匹配数,然后将每一组的单独最大不能匹配数相加就是我们的答案。
代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX_SCORE 1000
const int maxn=100000+5;
int cnt[MAX_SCORE+5],val[maxn],dp[maxn];
int n,k;
int main()
{
    
    //使用for 循环避免重叠子问题的产生,为非递归算法
	cin>>n>>k;
	memset(cnt,0,sizeof(cnt));//使cnt数组全部为0 
	int score,ans=0;
	for(int i=1;i<=n;i++)
	{
    
    
		cin>>score;
		cnt[score]++;//cnt[score]表示每一个数字有多少个重复的
	}
	//特殊处理k=0的情况
	if(k==0)
	{
    
     
		for(int i=0;i<=MAX_SCORE;i++)
		{
    
    
			if(cnt[i])
			ans++;//即有多少个不同的数字
		}
	}
	else
	{
    
    
		for(int i=0;i<k;i++)//i<k即可,当i>=k的时候,大于等于k的部分就为重复的部分
		{
    
    
			int m=0;
			for(int j=i;j<=MAX_SCORE;j+=k)
			{
    
    
				val[m++]=cnt[j];//创建一个新数组,存储每一组以i为首元素,以k为分数差的cnt数组
			}
			//使用新的数组dp来进行存储
			dp[0]=val[0];//其值为首元素的个数
			for(int j=1;j<m;j++)
			{
    
    
				if(j==1)
					dp[j]=max(dp[0],val[j]);//dp[1]只能选择两种
				else
					dp[j]=max(dp[j-2]+val[j],dp[j-1]);
			}
			ans+=dp[m-1];
		}
	}
	cout<<ans<<endl;
retuen 0;
}

猜你喜欢

转载自blog.csdn.net/malloch/article/details/108790883