1 条题解
-
0
自动搬运
来自洛谷,原作者为

妖怪i
**搬运于
2025-08-24 21:44:22,当前版本为作者最后更新于2018-10-05 16:27:03,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
此题一共有两个问题:
- 求金币分为两份的最小差值。
- 求分为最小差值时的方案数。
分步解答这两个问题。
第一个:
求两份金币的最小差值,那么我们很自然的想到,当两份金币相同时,差值最小。 那么题目就可以转化为,金币的价值最多能达到金币总价值的一半的多少。那么就是01背包了。
第二个:
直接求出第一问的金币价值的方案数即可。
下面贴下代码:
#include<bits/stdc++.h> #define mod 1000000 using namespace std; int n,a[350],tot,sum,f[500005]; long long dp[500005]; inline int read() { int x=0,f=1;char c=getchar(); while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return x*f; } int main() { n=read(); for(int i=1;i<=n;i++) a[i]=read(),sum+=a[i]; tot=sum; sum/=2; for(int i=1;i<=n;i++) for(int j=sum;j>=a[i];j--) f[j]=max(f[j],f[j-a[i]]+a[i]); printf("%d\n",tot-2*f[sum]); dp[0]=1; for(int i=1;i<=n;i++) for(int j=tot;j>=a[i];j--) dp[j]=(dp[j]+dp[j-a[i]])%mod; printf("%lld",dp[f[sum]]); return 0; }
- 1
信息
- ID
- 2074
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者