小Q的歌单

题目描述:小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌                    最多只能在歌单中出现一次,在不考虑歌单内歌曲的先后顺序的情况下,请问有多少种组成歌单的方法。

先试探一下看个图: 右下角即为所求   

                                                                                  

用vector< vector<int> > st的数据结构 st[i][j] 表示前j个歌长能组合成i歌长的情况

用vector<int> st 来保存单首歌长3 3 3 2 2 2 

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
	int k, lenx, x, leny, y;
	while (cin >> k >> lenx >> x >> leny >> y)
	{
		const int mod = 1e9+7;
		vector<int> v;
		for (int i = 0; i < x; ++i)
			v.push_back(lenx);
		for (int j = 0; j < y; ++j)
			v.push_back(leny);
		vector<vector<int> > st(k + 1, vector<int>(x + y, 1));
		for (int i = 1; i < k + 1; ++i)   //st[i][j] i代表
		{
			if (v[0]!=i)
			    st[i][0] = 0;     //考虑下标为1的那一列
			for (int j = 1; j < x + y; ++j)
			{
				if (i >= v[j])  //  合并后歌单长度大于单首歌长
				{
					st[i][j] = (st[i - v[j]][j - 1] + st[i][j - 1]) % mod;
				}
				else
					st[i][j] = (st[i][j - 1])% mod;
			}
		}
		cout << st[k].back()<< endl;
	}	
	system("pause");
	return 0;
}

最重要的是规律:  st[i][j] = (st[i - v[j]][j - 1] + st[i][j - 1]) % mod;  为了满足第2行规律需要把第0行先填充为全1

为了满足第1列规律需要把 行数i!=v[0]的置为1    这样就能保证整个st[i][j]都能满足规律

结果:  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值