爱的魔力转圈圈——2

第一层:1、输入 2、运算 3、输出
第二层:1、判断函数 2、输入数据 3、循环输出结果
第三层:计算
循环T组
每组判断
循环计算出多个可能和
每个可能和与k比较
相等
输出yes跳出循环
不相等
不跳出循环
比较完了,都不相等,输出no跳出循环
第四层:如何计算可能和 分组 一个相加,两个相加……以此类推
第五层:有n种药物,第一种吃了能转a[1]圈有t[1]片,第二种吃了能转a[2]圈有t[2]片,以此类推,第n种吃了能转a[n]圈有t[n]片,有人想通过吃药来转k圈(k是正整数),能否满足,能则输出yes,不能则输出no。

链接:https://www.nowcoder.com/questionTerminal/7f24eb7266ce4b0792ce8721d6259800
来源:牛客网

给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。

输入描述:
输入为两行:
第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
第二行为n个正整数Ai,以空格隔开。

输出描述:
输出所求的方案数
示例1
输入
5 15 5 5 10 2 3
输出
4



//递归会超时,只能过40%,用dp. dp[i][j]表示用前i个值组成和为j的方案个数(相比一维的,更容易理解一些)
#include <iostream>
#include <algorithm>
using namespace std;
//注意:最终结果int类型存不下,需要64位数据
//注意:dp不能放在main里,栈存不下。需要存在全局数据区
long long dp[1001][1001];
int main()
{
    int n,sum;
    cin>>n>>sum;
 
    int p[1000];
    for(int i = 1 ; i <= n ; i++)
        cin>>p[i];
//初始化dp,用前i个组成和为0的方案,只有1种,就是什么都不取,和为0;
    for (int i = 0 ; i < n ;i++)
    {
        dp[i][0] = 1;
    }
//用0个元素不能组成1~sum
    for (int j = 1 ; j < sum ;j++)
    {
        dp[0][j] = 0;
    }
 
    for (int i = 1 ; i <= n ;i++)
    {
        for (int j = 0 ; j<=sum ;j++)
        {
            if(p[i]<=j) dp[i][j] = dp[i-1][j]+dp[i-1][j-p[i]];
            else dp[i][j] = dp[i-1][j];
        }
    }
    cout<<dp[n][sum]<<endl;
    return 0;
}

算法总结)寻找组合数,求出从整数1到n中和为m的所有组合

奋斗的小炎 2018-07-12 12:44:15 4591 收藏
分类专栏: 编程 算法与数据结构 python
版权
采用背包问题原理,仅考虑具有最大的数字n是否存在与结果集合中,考虑以下两种情形:

(1)n在集合中,剩下的n-1个数字需要组成一个和为n-m的组合;

(2)n不在集合中,剩下的n-1个数字仍需要组成和为m的组合;

由于需要给出所有的组合可能,因此是一个回溯的过程。

算法设计思路:

由于是个回溯递归的过程,因此需要首先给出递归终止条件:当需要求和的数字小于等于0或所有数字都用完了的时候,就是程序终止的时候。

用一个列表数组item存储当前的候选集合,result列表存放最终的满足条件的结果,当满足条件时,将item加入result中。

因此,回溯的代码如下:

def find_combine(item, n, m, result):
    if n <= 0 or m <= 0:
        return
    if n == m:
        result.append(item + [n])
    item.append(n)
    find_combine(item, n-1, m-n, result)
    item.pop()
    find_combine(item, n-1, m, result)

用一组数字,运行一下,这里假设n=9,m=10

if __name__ == '__main__':
    item = []
    result = []
    find_combine(item, 9, 10, result)
    for r in result:
        print(r)

运行结果如下:

[9, 1]
[8, 2]
[7, 3]
[7, 2, 1]
[6, 4]
[6, 3, 1]
[5, 4, 1]
[5, 3, 2]
[4, 3, 2, 1]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值