题目描述
贝里斯和他的奶牛朋友组成一个团队去旅行了。他们每头奶牛都准备了一个背包,用来装旅行用的物品。他们的背包有两个特点:
1.每头奶牛的背包能装无限多的物品,每种物品有一个价值,但只能装一件;
2.每头奶牛都很有个性,所以每头奶牛的背包不会完全相同。
贝里斯的团队中有 M 头奶牛,那么对于整个团队,背包价值和最大是多少呢?
输入
从文件 team.in 中读入数据。
从文件 team.in 中读入数据。
第一行两个整数 M、N,表示团队的奶牛数和物品的数量。
接下来一行 N 个整数,表示每件物品的价值 wi。
数据保证不会出现有空背包奶牛的出现。
输出
输出到文件 team.out 中。
输出到文件 team.out 中。
一个整数,整个团队背包价值的最大值。
样例数据
输入 #1 复制
2 3 2 7 1
输出 #1 复制
19
输入 #2 复制
8 4 1 2 3 4
输出 #2 复制
58
数据范围限制
对于 30% 的数据,满足 1<=M,N<=15。
对于 60% 的数据,满足 1<=M<=200,1<=N<=100。
对于 100% 的数据,满足 1<=M<=1,000,000,1<=N<=500,0<wi<=50。
输出请注意使用 64 位整数(C++ 中的 long long)。
提示
【样例1解释】
19=(2+7+1)+(2+7)
【样例2解释】
58=(1+2+3+4)+(2+3+4)+(1+3+4)+(1+2+4)+(3+4)+(1+2+3)+(2+4)+(2+3)
思路:这是一道动态规划的题,可以每个物品循环一遍,因为数据只用25000,所以可以每个点都循环一遍,f[j]+=f[j-w[i]],f[i]代表承受i的重量有多少种可能数,(注意:由于承受0的重量也有1种可能,所以f[0]要被负初始值为1)然后从25000循环到0,如果m>0且还有可能每被算,且f[i]>0,那么ans+=i*min(m,f[i]),并m-=min(m,f[i]),最后输出一下就行了
AC代码:
#include<bits/stdc++.h>
using namespace std;
long long n,m,cnt;
long long a[505],
f[25005],s[25005];
long long ans;
int main()
{
freopen("team.in","r",stdin);
freopen("team.out","w",stdout);
scanf("%lld%lld",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%lld",&a[i]);
}
f[0]=1;
for(int i=1;i<=m;i++)
{
for(int j=25000;j>=a[i];j--)
{
f[j]+=f[j-a[i]];
}
}
for(int i=25000;i>=0;i--)
{
if(f[i]!=0)
{
s[++cnt]=i;
}
}
for(int i=1;i<cnt&&n>0;i++)
{
ans+=min(f[s[i]],n)*s[i],n-=min(f[s[i]],n);
}
printf("%lld",ans);
return 0;
}
1173

被折叠的 条评论
为什么被折叠?



