求个算法

求arr[]={0.25, 0.5, 1, 2, 4}中任意数相加=6的所有组合,包括自身相加。
...全文
193 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 7 楼 uuuououlcz 的回复:
写的好工整, 谢谢
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
谢谢大神
hui211314ddhui 2014-01-10
  • 打赏
  • 举报
回复
引用 9 楼 hui211314ddhui 的回复:
[quote=引用 8 楼 A38017032 的回复:] [quote=引用 6 楼 hui211314ddhui 的回复:] 所有的数都除以0.5,变成1,2,4,8,16相加得24, 1 = 00001,2 = 00010,4 = 00100,8 = 01000,16 = 10000, 24 = 11000,后面的自己想想吧...
这个怎么搞啊?[/quote] 用分支树画下看看,我仅仅提供个思路,行通行不通有待证明; [/quote] 额。。画错了,意思就是这样的
hui211314ddhui 2014-01-10
  • 打赏
  • 举报
回复
引用 8 楼 A38017032 的回复:
[quote=引用 6 楼 hui211314ddhui 的回复:]
所有的数都除以0.5,变成1,2,4,8,16相加得24, 1 = 00001,2 = 00010,4 = 00100,8 = 01000,16 = 10000,
24 = 11000,后面的自己想想吧...
这个怎么搞啊?[/quote]
用分支树画下看看,我仅仅提供个思路,行通行不通有待证明;

s126301 2014-01-10
  • 打赏
  • 举报
回复
用搜索 先将每个数都乘以4,化成整数来看比较简单 每次对于这个数, 我们可以选, 也可以不选, 如果超出总数的话, 就返回
#include <iostream>

const int data[] = {1, 2, 4, 8, 16};
const int SUM = 24;
const int N = 5;
int res[25], get[SUM << 1][N];

int dfs(int posSum, int pos, int posIndex)
{
	if(posSum > SUM)
	{
		return 0;
	}
	if(posSum == SUM)
	{
		for(int i = 0; i < pos; ++i)
		{
			printf("%d + ", res[i]);
		}
		printf(" %d = %d\n", res[pos - 1], SUM);
		return 1;
	}
	int sum = 0;
	for(int i = posIndex; i < N; ++i)
	{
		res[pos] = data[i];
		sum += dfs(posSum + data[i], pos + 1, i);
	}
	return sum;
}

int main()
{
	int sum = dfs(0, 0, 0);
	printf("%d\n",sum);
	return 0;
}
这个代码其实可以优化, 将每次的结果都记录下来, 如果有以前算过的, 就直接返回.这样速度会更快.
CoolEgos 2014-01-09
  • 打赏
  • 举报
回复
引用 6 楼 hui211314ddhui 的回复:
所有的数都除以0.5,变成1,2,4,8,16相加得24, 1 = 00001,2 = 00010,4 = 00100,8 = 01000,16 = 10000, 24 = 11000,后面的自己想想吧...
这个怎么搞啊?
还有多远 2014-01-09
  • 打赏
  • 举报
回复
话说这几个数刚好能精确表示呢,代码仅供参考

#include <utility>
#include <vector>
#include <iostream>
using namespace std;

void printPair(const pair<float,int>& p)
{
    for(int i = 0, n = p.second; i < n; ++i){
        if(i > 0) cout << "+";
        cout << p.first;
    }
}
void printVec(const vector<pair<float,int> >& v)
{
    for(int i = 0, s = v.size(); i < s; ++i){
        if(i > 0) cout << "+";
        printPair(v[i]);
    }
}

void solve(float arr[], int i, float remain, vector<pair<float,int> >& v)
{
    if(remain == 0){
        printVec(v);
        cout << "\n";
        return;
    }
    if(i < 0) return;
    
    //if can choose arr[i]
    if(remain >= arr[i]){    
        for(int n = remain / arr[i]; n > 0; --n){
            v.push_back(make_pair(arr[i], n));
            solve(arr, i - 1, remain - n * arr[i], v);
            v.pop_back();
        }
    }
    //do not choose arr[i]
    solve(arr, i - 1, remain, v);
}


int main()
{
    float arr[] = {0.25, 0.5, 1, 2, 4}, target = 6;
    vector<pair<float,int> > v;
    
    solve(arr, sizeof(arr)/sizeof(arr[0]) - 1, target, v);
    
    return 0;
}
hui211314ddhui 2014-01-09
  • 打赏
  • 举报
回复
所有的数都除以0.5,变成1,2,4,8,16相加得24, 1 = 00001,2 = 00010,4 = 00100,8 = 01000,16 = 10000, 24 = 11000,后面的自己想想吧...
赵4老师 2014-01-09
  • 打赏
  • 举报
回复
仅供参考
//问题是这样,有N个数字,数值不同,要列出用他们不同的组合相加等于1000的情况。
//比如,a[3]={200,300,400}
//则有的情况为:
//5 0 0
//3 0 1
//2 2 0
//1 0 2
//0 2 1
//等情况。
#include <stdio.h>
int a[3]={200,300,400};
int temp[3]={0,0,0};
void function(int sum, int index) {
    int j,i;

    if (sum==1000) {
        for (j=0;j<3;j++) printf("%d ",temp[j]);
        printf("\n");
        return;
    } else if (sum>1000) return;
    else for (i=index;i<3;i++) {
        temp[i]++;
        function(sum+a[i],i);
        temp[i]--;
    }
}
void main() {
    function(0,0);
}
//5 0 0
//3 0 1
//2 2 0
//1 0 2
//0 2 1
//
//n个(2<=n<=20)整数(整数范围-10<=x<=10),判断是否可以从这n个数中找到若干个数,其和为10
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <algorithm>
using namespace std;
int MAXN=20;
int MINN=2;
int x[20];
int n,i,j,k,sum;
int main() {
    srand((unsigned)time(NULL));
    n=MINN+rand()%(MAXN-1);
    for (i=0;i<n;i++) {
        x[i]=-10+rand()%21;
        printf("%d,",x[i]);
    }
    printf("\n");
    sort(&x[0],&x[n]);
    do {
        for (i=2;i<=n;i++) {
            sum=0;
            k=n/2-i/2;
            for (j=k;j<k+i;j++) {
                sum+=x[j];
            }
            if (10==sum) {
                for (j=k;j<k+i;j++) {
                    if (j==k+i-1) {
                        printf("%d==10\n",x[j]);
                    } else {
                        printf("%d+",x[j]);
                    }
                }
                printf("YES\n");
                return 1;
            }
        }
    } while (next_permutation(&x[0],&x[n]));
    printf("NO\n");
    return 0;
}
  • 打赏
  • 举报
回复
好的 我试一试
漫步者、 2014-01-09
  • 打赏
  • 举报
回复
其实这个刚好有个规律,后面的数字都是前面的2倍,那我从后面的两个数字相加,然后开始从这两个数字进行拆,看可以分成几个2几个1等等,这就好了。 但是如果没有规律的话,只能从最大的数字开始相加,然后拆分了。注意:采用回溯法做。
  • 打赏
  • 举报
回复
没有 比如说 6个1 1+1+1+1+1+1 = 6 0.25+0.25+0.25+0.25 + 4=6
漫步者、 2014-01-09
  • 打赏
  • 举报
回复
任意数?数字个数有限制?

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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