首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

01背包 求若干数的和为定值 【】代码有 求解释关键条件解决办法

2013-01-25 
01背包 求若干数的和为定值 【】代码有 求解释关键条件本帖最后由 titer1 于 2012-08-09 15:38:22 编辑//来

01背包 求若干数的和为定值 【】代码有 求解释关键条件
本帖最后由 titer1 于 2012-08-09 15:38:22 编辑


//来源v_july_v博客 
//输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,  
//使其和等于 m ,要求将其中所有的可能组合列出来。  
  
#include <stdio.h>  
#include <stdlib.h>  
#include <memory.h>  
  
/**  
 * 输入t, r, 尝试Wk 
 */  
void sumofsub(int t, int k ,int r, int& M, bool& flag, bool* X)  
{  
    X[k] = true;   // 选第k个数  
    if (t + k == M) // 若找到一个和为M,则设置解向量的标志位,输出解  
    {  
        flag = true;  
        for (int i = 1; i <= k; ++i)  
        {  
            if (X[i] == 1)  
            {  
                printf("%d ", i);  
            }  
        }  
        printf("/n");  
    }  
    else  
    {   // 若第k+1个数满足条件,则递归左子树  
     if (t + k + (k+1) <= M)  
        {  
            sumofsub(t + k, k + 1, r - k, M, flag, X);  
        }  
        // 若不选第k个数,选第k+1个数满足条件,则递归右子树  
       if ((t + r - k >= M) && (t + (k+1) <= M)) 
        {  
            X[k] = false;  
            sumofsub(t, k + 1, r - k, M, flag, X);  
        }  
    }  
}  
  
void search(int& N, int& M)  
{  
    // 初始化解空间  
    bool* X = (bool*)malloc(sizeof(bool) * (N+1));  
    memset(X, false, sizeof(bool) * (N+1));  
    int sum = (N + 1) * N * 0.5f;  
    if (1 > M || sum < M) // 预先排除无解情况  
    {  
        printf("not found/n");  
        return;  


    }  
    bool f = false;  
    sumofsub(0, 1, sum, M, f, X);  
    if (!f)  
    {  
        printf("not found/n");  
    }  
    free(X);  
}  
  
int main()  
{  
    int N, M;  
    printf("请输入整数N和M/n");  
    scanf("%d%d", &N, &M);  
    search(N, M);  
    return 0;  
}  



问题一:代码中 if ((t + r - k >= M) && (t + (k+1) <= M)) 具体表示什么?尤其(t + r - k >= M
问题二:问什么在void sumofsub(int t, int k ,int r, int& M, bool& flag, bool* X)  要专门设置一个 r参数
[解决办法]
思路就是把用过的组合存储起来。
不必每次调用。
[解决办法]
Q:问题一:代码中 if ((t + r - k >= M) && (t + (k+1) <= M)) 具体表示什么?尤其(t + r - k >= M

表示

t + r - k >= M
t表示已选中的数的和
r表示没有搜索到的数的总和
t+r-k 表示当前没有选中k时的总和

问题二:问什么在void sumofsub(int t, int k ,int r, int& M, bool& flag, bool* X) 要专门设置一个 r参数

这个我估计是为了防止异常

热点排行