专栏文章

题解:P9102 [PA 2020] Cukierki

P9102题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipmm4eg
此快照首次捕获于
2025/12/03 14:28
3 个月前
此快照最后确认于
2025/12/03 14:28
3 个月前
查看原文

大致思路

根据算法标签,可知这题是一道动态规划。
首先定义 dp[i][j]dp[i][j] 表示前 ii 个数能够表示 [1j][1,j] 这个范围中的所有数字。
由题显然可得:
  • dp[i][j]=dp[i1][j]dp[i][j]=dp[i-1][j] (在不选 a[i]a[i] 的情况)
  • dp[i][j]=dp[i1][ja[i]]dp[i][j]=dp[i-1][j-a[i]] (在选 a[i]a[i] 的情况)
很显然应为均为 i1i-1 ,所以这一维直接滚掉。
我们把数组从小到大排序,根据贪心可知,在 ai<aja_i<a_j 时,如果加上 aia_i 时,就大于总数,则 aja_j 就不用说了。

代码

CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e3,mod=1e9+7;
int n,a[maxn+5],f[maxn+5],ans;
signed main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",a+i);
	}
	sort(a+1,a+n+1);
	f[0]=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=maxn;j>=a[i]-1;j--)
		{
			int now=min(j+a[i],maxn);
			f[now]=(f[now]+f[j])%mod;
		}
	}
	for(int i=1;i<=maxn;i++)
	{
		ans=(ans+f[i])%mod;
	}
	printf("%d",ans);
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...