标题: 一个简单的算法题
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-11-28 15:02 资料 文集 短消息 只看该作者
一个简单的算法题

有n件商品,价格分别为:
v1, v2, v3, v4, ..., vn
有现金m元,求解是否可以从n件商品中选择若干件价格正好为m元。
求所有符合要求的组合,并输出每种组合中若干件商品的序号,若无符合要求的组合,输出无解。
注:价格v和m都是浮点数,n <=28

---------------------------------------------

当初选择n < 60太过随意了,测试了一下自己的代码,选择了一个时间可以接受的值n <= 28

[ 本帖最后由 Maxwell 于 2010-11-30 00:00 编辑 ]


顶部
性别:未知-离线 zhaohaidao

Rank: 5Rank: 5
组别 士兵
级别 破虏将军
功绩 8
帖子 787
编号 31614
注册 2005-1-31
家族 聚贤山庄


发表于 2010-11-29 00:01 资料 短消息 只看该作者
标记下,尝试用下贪心算法。。


顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-11-29 23:37 资料 文集 短消息 只看该作者


QUOTE:
原帖由 zhaohaidao 于 2010-11-29 00:01 发表
标记下,尝试用下贪心算法。。

贪心算法可以考虑,不过就是可能无法找到所有解。
顶部
性别:男-离线 周瑜

栎阳侯谏议大夫

Rank: 16
组别 翰林学士
级别 征西将军
好贴 10
功绩 943
帖子 4716
编号 1808
注册 2003-11-3
家族 瓦岗寨


发表于 2010-11-29 23:53 资料 主页 文集 短消息 只看该作者
我用递归法把程序写出来了,可惜复杂度太高,对于 n=60 无能为力。
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-11-30 00:01 资料 文集 短消息 只看该作者


QUOTE:
原帖由 周瑜 于 2010-11-29 23:53 发表
我用递归法把程序写出来了,可惜复杂度太高,对于 n=60 无能为力。

目前改为n <= 28了,其实没有仔细算过n应该取多少合适,你自己选择一个上限也没问题
顶部
性别:男-离线 周瑜

栎阳侯谏议大夫

Rank: 16
组别 翰林学士
级别 征西将军
好贴 10
功绩 943
帖子 4716
编号 1808
注册 2003-11-3
家族 瓦岗寨


发表于 2010-11-30 00:11 资料 主页 文集 短消息 只看该作者
代码如下,对于最糟糕的情况,28个1中找出总金额和为14的物品,不打印的情况下运行两秒完成,找出40116600种结果。

void printSum(double candidates[], int index[], int n)
{
        for (int i = 0; i < n; i++)
                cout << candidates[index[i]] << " ";
        cout << endl;
}

void getsum_help(double target, double sum, double candidates[], int size, int index[], int n)
{
        if (sum > target)
                return;
        if (fabs(sum-target) <= 1e-6*fabs(target))
                printSum(candidates, index, n);
        int starti = n==0 ? 0 : index[n-1]+1;
        for (int i = starti; i < size; i++)
        {
                index[n] = i;
                getsum_help(target, sum + candidates[i], candidates, size, index, n+1);
        }
}

void getsum(double target, double candidates[], int size)
{
        int *index = new int[size];
        getsum_help(target, 0, candidates, size, index, 0);
        delete []index;
}

顶部
性别:男-离线 周瑜

栎阳侯谏议大夫

Rank: 16
组别 翰林学士
级别 征西将军
好贴 10
功绩 943
帖子 4716
编号 1808
注册 2003-11-3
家族 瓦岗寨


发表于 2010-11-30 00:18 资料 主页 文集 短消息 只看该作者
由于 vi 和 m 都是浮点数,因此也就断绝了我使用动态规划的想法。

上述代码可能的优化包括:
1.先对 candidates 数组进行降序排列,这样前几步更容易得到超过 target 值的和,假设所有价格均为正数,则立即返回。
2.每一步比较当前总和与剩下所有数的和是否比 target 更小,如果更小,则理论上都不可能达到,立即返回。
顶部
性别:男-离线 dimeterio
(李秀辰)

Rank: 10Rank: 10Rank: 10Rank: 10
组别 校尉
级别 镇西将军
好贴 1
功绩 45
帖子 3985
编号 266634
注册 2008-2-7


发表于 2010-11-30 07:49 资料 个人空间 短消息 只看该作者 QQ
先作幾個判斷,進行預處理,速度是不是會快一點?

首先對Vi進行升序排列。
然後判斷,找出Min(Vn>m),把Vi>=Vn都剔除;
然後從V1開始累加,找出“最多多少個價格之和<=m”,然後決定不再對更多個價格累加進行嘗試。
顶部
性别:男-离线 阿尔法孝直
(雀力日进)

闽国公
遂安军节度使
★★★★★★

Rank: 19Rank: 19Rank: 19Rank: 19
柱国(正二品) 轩辕春秋年度最佳(游戏人生区)
组别 节度使
级别 卫将军
好贴 2
功绩 1796
帖子 6034
编号 19070
注册 2004-10-16
家族 轩辕雀党


发表于 2010-11-30 12:11 资料 个人空间 短消息 只看该作者 QQ


QUOTE:
原帖由 Maxwell 于 2010-11-28 15:02 发表
有n件商品,价格分别为:
v1, v2, v3, v4, ..., vn
有现金m元,求解是否可以从n件商品中选择若干件价格正好为m元。
求所有符合要求的组合,并输出每种组合中若干件商品的序号,若无符合要求的组合,输出无解 ...

我觉得题目表达有点奇怪:
按照出题的原意,似乎应该是:

有n商品,单价分别为:
v1, v2, v3, v4, ..., vn
有现金m元,求解是否可以从n商品中,每种选择若干件,总价正好为m元。

不过现在的题目表达的意思,似乎是,
有n商品,单价分别为:
v1, v2, v3, v4, ..., vn
有现金m元,求解是否可以从n商品中,每种选择一件,总价正好为m元。
顶部
性别:男-离线 周瑜

栎阳侯谏议大夫

Rank: 16
组别 翰林学士
级别 征西将军
好贴 10
功绩 943
帖子 4716
编号 1808
注册 2003-11-3
家族 瓦岗寨


发表于 2010-11-30 12:29 资料 主页 文集 短消息 只看该作者
我认为题目没有歧义,从v1到vn的n件商品选择若干件,每件商品都是唯一的,但可能有多件商品价值相等。

如果按照楼上的第一种理解,解题方法也非常相似,把我代码中 starti 处的 +1 去掉即可。

[ 本帖最后由 周瑜 于 2010-11-30 08:42 编辑 ]
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-11-30 22:46 资料 文集 短消息 只看该作者


QUOTE:
原帖由 周瑜 于 2010-11-30 00:18 发表
由于 vi 和 m 都是浮点数,因此也就断绝了我使用动态规划的想法。

上述代码可能的优化包括:
1.先对 candidates 数组进行降序排列,这样前几步更容易得到超过 target 值的和,假设所有价格均为正数,则立即 ...

如果用分做vi和m的单位,那就是整数了。

还可以做一些优化,不过不会有数量级上的变化了。28是我测试了穷举法能够在1分钟内执行完的一个值,看起来是给小了。
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2010-11-30 22:48 资料 文集 短消息 只看该作者


QUOTE:
原帖由 阿尔法孝直 于 2010-11-30 12:11 发表


我觉得题目表达有点奇怪:
按照出题的原意,似乎应该是:

有n种商品,单价分别为:
v1, v2, v3, v4, ..., vn
有现金m元,求解是否可以从n种商品中,每种选择若干件,总价正好为m元。

不过现在的题 ...

何谓出题原意?
顶部

正在浏览此帖的会员 - 共 1 人在线




当前时区 GMT+8, 现在时间是 2024-12-21 21:52
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.011838 second(s), 8 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP