列表

详情


NC210760. 能量水晶

描述

在MoveToEx打倒了巨龙之后获得了一颗神奇的能量水晶,他可以使用水晶中的能量来释放一些法术,但是很不幸,每一种法术他都只能释放一次.但是MoveToEx又想把水晶~~榨干~~.所以他必须把水晶用到不能再释放下一个法术为止.然后MoveToEx想知道,他有多少种方法释放法术.(注意,这里的方法仅指释放的法术种类不同而不包括释放的顺序不同).

输入描述

第一行包含两个整数,即MoveToEx能释放的法术的个数以及水晶的能量.
第二行有n个整数,表示每个法术所使用的能量值.

输出描述

输出一个整数,表示答案.

示例1

输入:

5 14
3 6 2 1 8

输出:

3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 3ms, 内存消耗: 380K, 提交时间: 2020-09-05 15:30:01

#include<bits/stdc++.h>
using namespace std;
long long a[3005],s[3005],dp[3005];
long long ans=0;
int main()
{
    long long n,m;
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lld",a+i);
    sort(a+1,a+n+1);
    s[1]=a[1];
    for(int i=2;i<=n;i++)s[i]=s[i-1]+a[i];
    dp[0]=1;
    for(int i=n;i>=1;i--)
    {
        for(int j=max(m-a[i]+1,s[i-1]);j<=m;j++)ans+=dp[j-s[i-1]];
        for(int j=m;j>=a[i];j--)dp[j]+=dp[j-a[i]];
    }
    cout<<ans<<endl;
    return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 3ms, 内存消耗: 456K, 提交时间: 2022-10-02 14:50:13

#include <bits/stdc++.h>
using namespace std;
int n,m,i,j,a[3005],sum[3005];
long long ans,dp[3005];
bool cmp(int x,int y){
	return x>y;
}
int main(){
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;++i) scanf("%d",&a[i]);
	sort(a+1,a+1+n,cmp);
	for(i=n;i>0;--i) sum[i]=sum[i+1]+a[i];
	dp[0]=1;
	for(i=1;i<=n;++i){
		for(j=m;j>-1;--j){
			if(m<a[i]) break;
			if(j+sum[i+1]>m-a[i]&&j+sum[i+1]<=m) ans+=dp[j];
	    }
		for(j=m;j>=a[i];--j) dp[j]+=dp[j-a[i]];
	}
	printf("%lld",ans);
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 3ms, 内存消耗: 376K, 提交时间: 2020-09-06 12:20:01

#include <bits/stdc++.h>
using namespace std;
int n,m;long long f[3010],a[3010],ans,s[3010];
int main()
{
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)
		s[i]=s[i-1]+a[i];
	f[0]=1;
	for(int i=n;i>=1;i--)
	{
		for(int j=max(m-s[i]+1,(long long )0);j<=m-s[i-1];j++)
			ans+=f[j];
		for(int j=m;j>=a[i];j--)
			f[j]+=f[j-a[i]];
	}
	printf("%lld",ans);
}

上一题