鱼C论坛

 找回密码
 立即注册
查看: 2170|回复: 3

题目201:总和唯一的子集

[复制链接]
发表于 2016-11-6 16:31:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Subsets with a unique sum

For any set A of numbers, let sum(A) be the sum of the elements of A.
Consider the set B = {1,3,6,8,10,11}.
There are 20 subsets of B containing three elements, and their sums are:

   屏幕快照 2016-11-06 下午4.26.12.png

Some of these sums occur more than once, others are unique.
For a set A, let U(A,k) be the set of unique sums of k-element subsets of A, in our example we find U(B,3) = {10,12,14,18,21,25,27,29} and sum(U(B,3)) = 156.

Now consider the 100-element set S = {12, 22, ... , 1002}.
S has 100891344545564193334812497256 50-element subsets.

Determine the sum of all integers which are the sum of exactly one of the 50-element subsets of S, i.e. find sum(U(S,50)).


题目:

对于数字组成的任意集体 A,定义 sum(A) 为 A 中元素的和。

考虑集合 B = {1,3,6,8,10,11}

B 中包含三个元素的子集共有 20 个,他们的和分别是:

   屏幕快照 2016-11-06 下午4.29.08.png

某些和值出现不只一次,其它的则是唯一的。

对于集合 A,定义 U(A,k) 为 A 中 k 个元素子集的唯一和值的集合。在上例中,我们得到 U(B,3) = {10,12,14,18,21,25,27,29} ,而 sum(U(B,3)) = 156。

现在考虑有一百个元素的集合 S = {12, 22, ... , 1002}。

它的包含 50 个元素的子集总共有 100891344545564193334812497256 个。

请对上面那 100891344545564193334812497256 个集合,找出它们唯一和的集合 U(S,50),求 sum(U(S,50))。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-31 23:00:32 | 显示全部楼层
本帖最后由 fc1735 于 2018-7-31 23:05 编辑

brute force
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define SIZE 100
  4. #define VOLUME 50
  5. #define BOUND (SIZE*(SIZE+1)*(SIZE*2+1)/6)
  6. typedef struct node{
  7.         int N;
  8.         struct node* next;
  9. }node;

  10. typedef struct{
  11.         node head;
  12.         int bucket[BOUND];
  13. }type;

  14. static type sum[VOLUME];

  15. void init(int *A)
  16. {
  17.         for(int i=1,j=1;i<=SIZE;i++){
  18.                 *A++=j;
  19.                 j+=i+i+1;
  20.         }
  21. }
  22. int main()
  23. {
  24.         int N[SIZE];
  25.         init(N);
  26.         for(int i=0;i<SIZE;i++){
  27.                 for(int j=i>=VOLUME?VOLUME-1:i,k=i-VOLUME;j>=k&&j;j--){
  28.                         node *p=sum[j-1].head.next;
  29.                         while(p){
  30.                                 if(!(sum[j].bucket[p->N+N[i]])){
  31.                                         node *tmp=malloc(sizeof *tmp);
  32.                                         tmp->N=p->N+N[i];
  33.                                         tmp->next=sum[j].head.next;
  34.                                         sum[j].head.next=tmp;
  35.                                 }
  36.                                 sum[j].bucket[p->N+N[i]]+=sum[j-1].bucket[p->N];
  37.                                 p=p->next;
  38.                         }
  39.                 }
  40.                 sum[0].bucket[N[i]]+=1;
  41.                 node *tmp=malloc(sizeof *tmp);
  42.                 tmp->N=N[i];
  43.                 tmp->next=sum[0].head.next;
  44.                 sum[0].head.next=tmp;
  45.         }
  46.         int total=0;
  47.         for(int i=0;i<BOUND;i++){
  48.                 if(sum[VOLUME-1].bucket[i]==1)
  49.                         total+=i;
  50.         }
  51.         printf("%d\n",total);

  52.         return 0;
  53. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-11 21:30:25 | 显示全部楼层

弱弱问下,有生之年这个程序能运行完吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-5 13:08:46 | 显示全部楼层
本帖最后由 fc1735 于 2019-10-5 13:39 编辑
gunjang 发表于 2019-8-11 21:30
弱弱问下,有生之年这个程序能运行完吗?

  1. S = map(lambda x: x**2, range(1, 101))
  2. U = list(map(lambda x: {}, range(51)))
  3. U[0][0] = 1
  4. for i in S:
  5.   for j in reversed(range(50)):
  6.     for k in U[j]:
  7.       U[j+1][k+i] = U[j+1].get(k+i, 0) + U[j][k]
  8. print(sum(map(lambda x: x[0], filter(lambda x: x[1] == 1, U[50].items()))))
复制代码


用python写的, 大约要跑2分钟, 不用dict的话可以1秒跑完
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-1 05:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表