Niu Ke Energy Crystal

After sorting from small to large
We can set up a scheme, the consumption of magic looks like this: starting from 1 to choose a continuous segment of smaller magic, and then choose several scattered larger magic.
So we need to enumerate. The first magic that is not selected, and the continuous smaller magic before it, all need to be selected in this enumeration. As for the number of scattered larger magic options selected later, dp count (knapsack count).
Then we take an example to illustrate:
5 14
3 6 2 1 8
After sorting:
5 14
1 2 3 6 8
When we set 8 to be the first smaller magic that is not selected, the larger magic after 8 will be counted by dp.
When we set 6 to be the first smaller magic that is not selected, the larger magic after 6 is counted once by dp.
When we set 3 to be the first smaller magic that is not selected, the larger magic after 3 is counted once by dp.
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e3+5; 
int n,m,ans;
int a[N],sum[N],f[N];
signed main(){
    
    
	scanf("%lld%lld",&n,&m);
	for (register int i=1; i<=n; ++i) scanf("%lld",&a[i]); 
	sort(a+1,a+n+1);
	for (register int i=1; i<=n; ++i) sum[i]=sum[i-1]+a[i];
	f[0]=1;
	for (register int i=n; i>=1; --i)
	{
    
    
		if (sum[i-1]<=m)
		for (register int j=max(0ll,m-sum[i]+1); j<=m-sum[i-1]; ++j) ans+=f[j];
		//当最小的不选的数为6时,我们发现,只要再在[3,8]内选任意魔法即可
		//后面至少要选总大小为 max(0,m-sum[i]+1)的魔法数,不然6就可以被选进去了
		//后面最多能选的魔法数为:m-sum[i-1],即还剩下的空间 
		for (register int j=m; j>=a[i]; --j) f[j]+=f[j-a[i]];	
	}
	printf("%lld\n",ans);
return 0;
}

Guess you like

Origin blog.csdn.net/Dove_xyh/article/details/108414280