博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hdu 1709 The Balance
阅读量:5297 次
发布时间:2019-06-14

本文共 3123 字,大约阅读时间需要 10 分钟。

题目链接:

 

题意:

     给N个整数,每个数只能使用一次。将他们组合起来,最后看在1~sum(a[1]..a[N])这些数里有多少数是这N个数组合不出来的.

     先输出这些数的个数,再将这些数输出来。如果个数是0,那么不需要输出数。 

     案例分析:

     input:

     3

     1 2 4

     output:

     0

     -->1(||4-1-2) , 2(||4-2) , 1+2(||4-1) , 4  , 1+4 , 2+4 , 1+2+4.

思路分析:

     可以将这N个数看成是N个物品。就将这个问题转化成了一个0-1背包问题,那么,所有的加法组合就可以求出来。那么减法呢?

     依旧是上面的案例,由于这组案例比较特殊。 只需加法组合便可以将1~sum(a[1]..a[N])全部组合出来.不过并不妨碍分析减法组合过程。

     0-1背包解法得到的加法组合必然是一个以上物品组合起来的(这个是无需置疑的),那么减法无非是减少组合的物品个数

     如 (4+1)-1=4 --> 4+1的组合减去1的组合 得到了一个新的组合。

     看第二个案例或许更明白:

     3

     9 2 1

     先将加法组合用0-1背包解出来:

     1 , 2 , 1+2 , 9 , 1+9 , 2+9 , 1+2+9 .

     这是所有的加法组合,接下来利用加法求减法组合。

     2-1=1 , (1+2)-1=2 , 9-1=8 , (1+9)-1=9 , (2+9)-1=10 , (1+2+9)-1=11.

     (1+2)-1=2 , 9-2=7 , (1+9)-2=8 , (2+9)-2=9 , (1+2+9)-2=10.

     9-(1+2)=6 , (9+1)-(1+2)=7 , (2+9)-(1+2)=8 , (1+2+9)-(1+2)=9.

     ...

     ...

     最后所有的减法都暴力扫完之后,发现 4和5这两个数字是组合不出来的。

     所以答案便是 2 个数 4和5 了。

代码如下:

     

1 #include 
2 #include
3 #include
4 #include
5 using namespace std; 6 #define MAX 101 7 int w[MAX*MAX],c[MAX*MAX];//w->价值,c->所需空间花费; 8 bool flag[MAX*MAX]; 9 int f[MAX*MAX];10 int x[MAX*MAX];11 int p[MAX*MAX];12 int n,v,ans;13 void init()14 {15 memset(w,0,sizeof(w));16 memset(c,0,sizeof(c));17 memset(f,0,sizeof(f));18 memset(p,0,sizeof(p));19 memset(x,0,sizeof(x));20 memset(flag,false,sizeof(flag));21 v=0;22 ans=0;23 }24 void out()25 {26 for(int i=0;i<=v;i++)27 cout<
<<" ";28 cout<
=c[i];j--)46 {47 if(f[j]>=0) flag[f[j]]=true;48 f[j]=max(f[j],f[j-c[i]]+w[i]);49 if(f[j]>=0) flag[f[j]]=true;50 }51 //out();52 for(i=0;i<=v;i++)//找出所有加法组合;53 if(flag[i]) x[k++]=i;54 55 for(i=0;i
=0) flag[x[j]-x[i]]=true;58 59 for(i=0;i<=v;i++)60 if(!flag[i]) p[ans++]=i;61 62 printf("%d\n",ans);63 if(!ans) return ;64 for(i=0;i
View Code

 

     还有一种常见的方法便是母函数~~

     是不是很像呢. 把这n个数看成是n克的砝码,每个砝码只有一个

     母函数的思路就不赘诉了 , 不知道的朋友可以百度学习一下。

     这里需要改动一点点的便是:在合并的过程中加入减法合并。

     只是需要注意 每个砝码只有一个。

代码如下:

1 #include 
2 #include
3 #include
4 #include
5 using namespace std; 6 #define MAX 101 7 int num[MAX]; 8 int c1[MAX*MAX]; 9 int c2[MAX*MAX];10 int ans[MAX*MAX];11 int n,sum;12 void init()13 {14 sum=0;15 memset(c1,0,sizeof(c1));16 memset(c2,0,sizeof(c2));17 }18 void read()19 {20 for(int i=1;i<=n;i++)21 {22 scanf("%d",&num[i]);23 sum+=num[i];24 }25 }26 void cal()27 {28 int i,j,k;29 int count=0;30 c1[0]=c1[num[1]]=1;31 for(i=2;i<=n;i++)32 {33 for(j=0;j<=sum;j++)34 for(k=0;k+j<=sum&&k<=num[i];k+=num[i])35 {36 if(j>=k) c2[j-k]+=c1[j];37 else c2[k-j]+=c1[j];38 c2[j+k]+=c1[j];39 }40 for(j=0;j<=sum;j++)41 {42 c1[j]=c2[j];43 c2[j]=0;44 }45 }46 for(i=1;i<=sum;i++)47 {48 if(!c1[i])49 {50 ans[count++]=i;51 }52 }53 printf("%d\n",count);54 if(!count) return ;55 for(i=0;i
View Code

 

转载于:https://www.cnblogs.com/By-ruoyu/p/3913494.html

你可能感兴趣的文章
Oracl数据库管理方面的资料(查询sga,查看oracle数据库名称sid,查看oracle数据库名称,查看表空间,修改表空间名称)...
查看>>
mobx react
查看>>
Windows Phone 7你不知道的8件事
查看>>
Eclipse配置Maven
查看>>
无责任Windows Azure SDK .NET开发入门篇二[使用Azure AD 进行身份验证--2.1使用Azure AD需要了解几个概念]...
查看>>
python字符串函数总结
查看>>
linux查看是否安装JDK(转载)
查看>>
游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
查看>>
[新]最近用unity5弄的一些渲染
查看>>
mybatis-servlet.xml配置SpringMVC样板
查看>>
启动eclipse是报 no java virtual machine was found after searching the following location
查看>>
ZOJ Problem Set Vol 1(Update paste)
查看>>
头文件dirent.h
查看>>
lol人物模型提取(八)
查看>>
USACO / Factorials (简单模拟)
查看>>
5月4日上午学习日志
查看>>
(译)IOS block编程指南 2 block开始
查看>>
Data Structure Binary Tree: Lowest Common Ancestor in a Binary Tree
查看>>
java第二次作业
查看>>
Java 9 揭秘(14. HTTP/2 Client API)
查看>>