2985_数字组合

/*
	Name: 2985_数字组合
	Copyright: 
	Author: 
	Date: 26-07-17 22:52
	Description: 2985_数字组合
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式。如:
n=5,5个数分别为1,2,3,4,5,t=5;
那么可能的组合有5=1+4和5=2+3和5=5三种组合方式。
输入
输入的第一行是两个正整数n和t,用空格隔开,其中1<=n<=20,表示正整数的个数,t为要求的和(1<=t<=1000)
接下来的一行是n个正整数,用空格隔开。
输出
和为t的不同的组合方式的数目。
样例输入
5 5
1 2 3 4 5
样例输出
3

算法分析:这是一个典型的0-1背包问题,只不过不是求最优解,而是求所有可能的组合,故需要累计所有的组合。 
*/
#include<iostream>

using namespace std;

const int MAXC = 10000; //背包最大容量 
const int MAXN = 100; //物品的最大个数
int V[MAXN+1];//第i个数的值相当于0-1背包中物品的重量和价值 
long long F[MAXC+1] = {1}; //记录给定n个物品装入容量为j的背包的分配方案数量 

long long ZeroOnePack_5(int n, int c);//可以转化为求0-1背包的方案总数

int main() 
{
	int n, c;
	cin >> n >> c;
	
	for (int i=1; i<=n; i++)//不计下标为0的元素 
	{
		cin >> V[i];
	}
	
	cout << ZeroOnePack_5(n, c) << endl; 
	
	return 0;
}

long long ZeroOnePack_5(int n, int c)//可以转化为求0-1背包的方案总数 
{
 	for (int i=1; i<=n; i++)
	{//须先求出列坐标j较大的F[j],故让循环变量j的值从大到小递减
		for (int j=c; j>=V[i]; j--)
		{//当(j < V[i])时,F[j]的值不变,即没有产生新的方案 
			F[j] += F[j-V[i]];
		}
	}
	
	return F[c];
}

/*
	Name: 2985_数字组合
	Copyright: 
	Author: 
	Date: 26-07-17 22:52
	Description: 2985_数字组合
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式。如:
n=5,5个数分别为1,2,3,4,5,t=5;
那么可能的组合有5=1+4和5=2+3和5=5三种组合方式。
输入
输入的第一行是两个正整数n和t,用空格隔开,其中1<=n<=20,表示正整数的个数,t为要求的和(1<=t<=1000)
接下来的一行是n个正整数,用空格隔开。
输出
和为t的不同的组合方式的数目。
样例输入
5 5
1 2 3 4 5
样例输出
3

算法分析:这是一个典型的0-1背包问题,只不过不是求最优解,而是求所有可能的组合,故需要累计所有的组合。
*/
#include<iostream>

using namespace std;

const int MAXC = 1000; //背包最大容量 
const int MAXN = 20; //物品的最大个数
int V[MAXN+1];//第i个数的值相当于0-1背包中物品的重量和价值 
long long B3[MAXN+1][MAXC+1] = {1}; //记录给定n个物品装入容量为j的背包的分配方案数量

int ZeroOnePack_3(int n, int c);//可以转化为求0-1背包的方案总数

int main() 
{
	int n, c;
	cin >> n >> c;
	
	for (int i=1; i<=n; i++)//不计下标为0的元素 
	{
		cin >> V[i];
	}
	
	cout << ZeroOnePack_3(n, c) << endl; 
	
	return 0;
}

int ZeroOnePack_3(int n, int c)//可以转化为求0-1背包的方案总数
{
 	for (int i=1; i<=n; i++)
	{
		for (int j=0; j<=c; j++) //注意j一定要从0开始 
		{ 
			B3[i][j] = B3[i-1][j];
			if (j >= V[i])//装物品i后,产生了新方案 
				B3[i][j] += B3[i-1][j-V[i]];
		}
	}
		
	return B3[n][c];
}

/*
	Name: 2985_数字组合
	Copyright: 
	Author: 
	Date: 26-07-17 22:52
	Description: 2985_数字组合
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式。如:
n=5,5个数分别为1,2,3,4,5,t=5;
那么可能的组合有5=1+4和5=2+3和5=5三种组合方式。
输入
输入的第一行是两个正整数n和t,用空格隔开,其中1<=n<=20,表示正整数的个数,t为要求的和(1<=t<=1000)
接下来的一行是n个正整数,用空格隔开。
输出
和为t的不同的组合方式的数目。
样例输入
5 5
1 2 3 4 5
样例输出
3

算法分析:这是一个典型的0-1背包问题,只不过不是求最优解,而是求所有可能的组合,故需要累计所有的组合。
*/
#include<iostream>

using namespace std;

const int MAXC = 10000; //背包最大容量 
const int MAXN = 100; //物品的最大个数
int V[MAXN+1];//第i个数的值相当于0-1背包中物品的重量和价值 
long long B3[MAXN+1][MAXC+1] = {1}; //记录给定n个物品装入容量为j的背包的分配方案数量

int ZeroOnePack_3(int n, int c);//可以转化为求0-1背包的方案总数

int main() 
{
	int n, c;
	cin >> n >> c;
	
	for (int i=1; i<=n; i++)//不计下标为0的元素 
	{
		cin >> V[i];
	}
	
	cout << ZeroOnePack_3(n, c) << endl; 
	
	return 0;
}

int ZeroOnePack_3(int n, int c)//可以转化为求0-1背包的方案总数
{
 	for (int i=1; i<n; i++)
	{   //注意j一定要从0开始 
		for (int j=0; j<V[i]; j++) //不能装入物品i,即没有产生新的组合方案 
			B3[i][j] = B3[i-1][j];
		for (int j=V[i]; j<=c; j++) //能装入物品i,即产生了新的组合方案 
			B3[i][j] = B3[i-1][j] + B3[i-1][j-V[i]];		
	}
	B3[n][c] = B3[n-1][c];//不装物品n时的方案总数量 
	if (c >= V[n])//装物品n后,产生了新方案 
		B3[n][c] += B3[n-1][c-V[n]]; 
		
	return B3[n][c];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值