求助,一个有点棘手的数字分解算法

programjun 2007-05-18 09:12:10
问题如下:
已知一个数A,求出A=x1+x2+x3+x4的所有组合,其中,x1,x2,x3,x4的最小值为1,他们的最大值分别为给定的一个数字。
例如:A=60,x1,x2,x3,x4的最大值分别为x1=13,x2=26,x3=24,x4=19,则求出这几个数相加得60的所有组合。
若有好的算法,不胜感谢!
...全文
466 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
daniel_yao 2007-05-30
  • 打赏
  • 举报
回复
计算A=60,当x1>13的所有组合时
相当于计算(13+x1`)+x2+x3+x4=60
daniel_yao 2007-05-30
  • 打赏
  • 举报
回复
1、计算A=60,x1,x2,x3,x4的所有组合M。
2、计算A=60,当x1>13的所有组合。依次当x2>26 ,x3>24 ,x4>19,的所有组合M1。
3、计算A=60,当x1>13和x2>26的所有组合,还有其他的两两结合的组合 计算得M2
4、计算A=60,当x1>13和x2>26和x3>24的所有组合,以及其他三三结合的组合 计算得M3
5、计算A=60当x1>13和x2>26和x3>24和x4>19的所有组合M4

最后M1-M2+M3-M4
geeksky 2007-05-29
  • 打赏
  • 举报
回复
要么搜索,要么动规,搜索简单点
超级大笨狼 2007-05-29
  • 打赏
  • 举报
回复
穷举ok
abc130314 2007-05-28
  • 打赏
  • 举报
回复
我的想法是,先看成 A=x1+A1, A2=x2+x3+x4;

A1=x2+A2,A2=x3+A4
……
以此类推,代码如下

public class Main {
private static final int idim[]={13,26,24,19}; //题目给定的各个数的最大值
private static final int n=60; //所求的和
private static int isum[]=new int [idim.length-1]; //为打印各组合准备的数组
private static int is=0; //记录总共有多少种结果
private static final int or=1; //0,不打印各组合,只打印结果总数;1,打印各组合
public static void main(String args[]) {
int a=0;
for (int i = 0; i < idim.length; i++) {
a+=idim[i];
}
if (a<n) {
System.out.print("无解。");
System.exit(0);
}
f(1,n); //进行 A = x1+ A1。
//1 是标记x;n 表示 x+剩下的数的和
System.out.print(is);
}
public static void f( int x,int y ) {
if ( x==idim.length ) {
if (or==1) {
int a=0;
for (int i = 0; i < x-1; i++) {
a+=isum[i];
System.out.print(isum[i]+"\t");
}
System.out.print((n-a)+"\n");
}
is++;
} else {
int a=0;
for (int i = x; i < idim.length; i++) {
a+=idim[i];
}
int b=( (1+a)>y ) ? 1:(y-a);
int c=( idim[x-1]+1>y ) ? (y-1):idim[x-1];
for (int i = b; i < c+1; i++) {
isum[x-1]=i;
f(x+1,y-i);
}
}
}
}
abc130314 2007-05-28
  • 打赏
  • 举报
回复
mark
fire_woods 2007-05-22
  • 打赏
  • 举报
回复
穷举
FireElement 2007-05-21
  • 打赏
  • 举报
回复
若x1,x2,x3,x4的最大值加在一起也小于A,则无解
然后是遍历,遍历时的方法如下,对于Xi,遍历范围是A-(Max(X(i+1))+...+Max(X4))到Max(Xi)
也就是对于X1,范围是1~13,对于X2,由于60-24-19-X1到26,以此类推。
public class Summary
{
public static void main(String[] args)
{
int maxX1 = 13;
int maxX2 = 26;
int maxX3 = 24;
int maxX4 = 19;
int sum = 60;
int l;
for (int i = max(sum - maxX2 - maxX3 - maxX4, 1); i <= maxX1; i++)
{
for (int j = max(sum - i - maxX3 - maxX4, 1); j <= maxX3; j++)
{
for (int k = max(sum - i - j - maxX4, 1); k <= maxX3; k++)
{
l = sum - i - j - k;
if (l > 0)
{
System.out.println(i + " " + j + " " + k + " " + l);
}
}
}
}
}

private static int max (int i, int j)
{
if (i > j)
{
return i;
}
return j;
}
}
hertz2007 2007-05-19
  • 打赏
  • 举报
回复
#include"iostream"
#include"fstream"
using namespace std;

int main()
{
int x1,x2,x3,x4,num=0;
const sum=60;
const int mx1=13,mx2=26,mx3=24,mx4=19;

ofstream fout("result.txt",ios::out);

for(x1=1;x1<mx1;x1++)
for(x2=1;x2<mx2;x2++)
for(x3=1;x3<mx3;x3++)
{
x4=sum-x1-x2-x3;
if(x4>=1&&x4<=mx4)
{
fout<<"x1="<<x1<<" x2="<<x2<<" x3="<<x3<<" x4="<<x4<<endl;
num++;
}
}

fout<<"Total number of solutions: "<<num<<endl;

fout.close();

return 0;
}
suprwx 2007-05-18
  • 打赏
  • 举报
回复
纠正: 是 A-1 的 n-1 的组合, 去除不满足条件的和重复的结果。
likilaka 2007-05-18
  • 打赏
  • 举报
回复
记得本科的时候学过
这个是典型的运筹学里面的线性规划问题
使用单纯型法就可以
如果再加个最优条件就变成线性规划的最优化问题了(可以用单纯型法也可以用动态规划来算)
楼主可以找本运筹的书来看看,呵呵,忘得差不多了。。。
suprwx 2007-05-18
  • 打赏
  • 举报
回复
提示:

1 * 2 3 * 4 ... * ...57 58 59 60 ... A

* 为分隔符,要把 A 分为 n 个数的和就有 n-1 个*
然后求 A 的 n-1 的组合(即 * 的位置),再用位置相减得出每个数字。
比如求出组合1, 3, 56 则
x1 = 1 - 0 = 1
x2 = 3 - 1 = 2
x3 = 56 - 3 = 53
x4 = 60 - 56 = 4
再去除重复得结果即可

stl 可以产生组合
Gipee 2007-05-18
  • 打赏
  • 举报
回复
既然是“所有组合”,最必须是穷举。可用三套for循环,但其中略有讲究。
为了避免重复,我们先约定 x1 <= x2 <= x3 <= x4
由此可见
x1 <= (int)(A / 4)
x2 <= (int)(A / 3) && x2 >= x1
……

for(int x1 = 1; x1 <= A/4; x1++)
for(int x2 = x1; x2 <= A/3; x2++)
for(int x3 = x2; x3 <= A/2; x3++) {
int x4 = A - x1 - x2 - x3;
if(x4 < x3) break;
else 输出:x1, x2, x3, x4
}





medie2005 2007-05-18
  • 打赏
  • 举报
回复
求所有组合,是没有好解法的,这明显是一个遍历问题,对A,x1,x2,x3,x4较大的情况,符合条件的组合是很多的,运算时间短不了。

如果是求组合个数,那才有意思。

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧