当前位置:   article > 正文

蓝桥杯大赛青少年创意编程C++高级组模拟题-题目的分数值_主办方希望:解决更多问题的参赛者的排名更高。 因此,对于任何解决了 k(1≤k≤n-1)

主办方希望:解决更多问题的参赛者的排名更高。 因此,对于任何解决了 k(1≤k≤n-1)

最近辅导蓝桥杯青少年组,遇到此题网上无题解,自己写了一份。

编程实现: 题目的分数值

程序命名: score.cpp

题目描述:

有n个问题,现在请你给这n个问题分配分值。

n个问题已经按从简单到困难排好序,第i个问题的分值是Ai,n个问题的分值满足如下关系:1<=A1<=A2<=…<=An<=n。不同的问题可以具有相同的分值。

主办方希望:解决更多问题的参赛者的排名更高。因此,对于任何解决了k(1 <=k<=n-1)个问题的参赛者,其分数总和一定要小于解决了任何k+1个问题的参赛者的分数总和。

你有几种分配分值的方法?将答案对素数m取余后输出。

输入:

整数n和m

其中2<=n<=5000,9x108 <m<109,m为素数。

输出:

分值分配的方案数对m取余后的数字

样例输入1

2 998244353

样例输出1:

3

样例1说明:

2个题的分值分配有3种方案:(1,1),(1,2),(2,2)。

样例输入2:

3 998244353

样例输出2:

7

样例2说明:

3个题的分值分配有7种方案:(1,1,1),(1,2,2),(1,3,3),(2,2,2),(2,2,3),(2,3,3),(3,3,3)

思路

首先对题目分析。
要保证做K+1个题目得分比做K个高,则要求满足任意两个题目分值大于任意第三个题目,又A1和A2为分值最小的两个题目。则有:Ai>A1+A2。
A1和A2的分值可以通过枚举选取,从第三个题目开始,每个题目的分值须满足Ai>=Ai-1,且Ai<=min(n,A1+A2-1)。
然后递推,定义子问题。
后续的分值选取方案数与当前分值选取有关。
设dp[i][k]表示后续还剩i个未确定分值的题目,且当前题目可选方案为k种的总方案数。每个题目的分值方案数满足递推式:
在这里插入图片描述
递推边界为:dp[1][k] = k
观察递推式具有累加性质,可优化为:
在这里插入图片描述
对定义的dp值先做预处理,原问题等价于先取了前两个数,后续的A3按照约束有k1种取法,k1 = min(A1,n-A2+1),依次是A2 ~ k1,按加法原理,此时对答案贡献dp[n-2][k1]
由数论基本定理,对答案取模等价于对加法运算中各步骤结果取模的总和再取模。

编写代码如下:

#include<iostream>
using namespace std;
const int MAXN = 5005;
int dp[MAXN][MAXN];
int main()
{
	
	int n,m;
	cin>>n>>m;
	for(int k=1;k<=n;k++) dp[1][k] = k;
	for(int i=2;i<=n;i++)  // 后面还有几个数 
	{
		for(int k=1;k<=n;k++)  //当前阶段有多少种选择 
		{
			if(k==1) dp[i][k] = dp[i-1][k];
			else dp[i][k] = (dp[i][k-1] + dp[i-1][k]) % m; 
		}
	}
	int ans = 0;
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j<=n;j++)
		{
			int k1= min(i,n-j+1);
			ans = (ans + dp[n-2][k1]) % m;
		}
	}
	if(n==2) 
		ans = 3;
	cout<<ans<<endl;
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/393130
推荐阅读
相关标签
  

闽ICP备14008679号