腾讯笔试:小Q的歌单

时间限制:1秒

空间限制:32768K

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

输入描述:

每个输入包含一个测试用例。
每个测试用例的第一行包含一个整数,表示歌单的总长度K(1<=K<=1000)。
接下来的一行包含四个正整数,分别表示歌的第一种长度A(A<=10)和数量X(X<=100)以及歌的第二种长度B(B<=10)和数量Y(Y<=100)。保证A不等于B。

输出描述:

输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对1000000007取模的结果。

输入例子1:

5
2 3 3 3

输出例子1:

9
#include <map>  
#include <cmath>  
#include <queue>  
#include <cstdio>  
#include <string>  
#include <cstring>  
#include <iostream>  
#include <algorithm> 
#include <sstream> 
#include <time.h> 
#include <vector>
#include <list>
#include <iostream>
#include<iomanip>
#include<time.h>  

#define N_MAX 205
#define INF (0x3f3f3f3f)
#define Q (1000000007)

using namespace std;

long long Data[201][1001];
int Length[201];
int main()
{
	int N, A, X, B, Y;
	cin >> N >> A >> X >> B >> Y;
	memset(Data, 0, sizeof(Data));
	for (int i = 1; i <= X; ++i)
	{
		Length[i] = A;
        Data[i][0] = 1;
	}
	for (int i = X + 1; i <= X + Y; ++i)
	{
		Length[i] = B;
        Data[i][0] = 1;
	}
    Data[0][0] = 1;
	for (int i = 1; i <= X + Y; ++i)
	{
		for (int j = 0; j <= N; ++j)
		{
			//当大于该商品价值时,可能性为不选择该商品的值与选择该商品的值的和
			if (j >= Length[i])
				Data[i][j] = (Data[i - 1][j] % Q + Data[i - 1][j - Length[i]] % Q)% Q;
			else
				Data[i][j] = Data[i - 1][j] % Q;
		}
	}
	cout << Data[X + Y][N] << endl;
	return 0;
}
发布了104 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Yanpr919/article/details/100185455