每个输入包含一个测试用例。
每个测试用例的第一行包含一个整数,表示歌单的总长度K(1<=K<=1000)。
接下来的一行包含四个正整数,分别表示歌的第一种长度A(A<=10)和数量X(X<=100)以及歌的第二种长度B(B<=10)和数量Y(Y<=100)。保证A不等于B。
输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对1000000007取模的结果。
5 2 3 3 3
9
#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int a,x,b,y,k;
long long dp[1010];
int p[210];
int main() {
scanf("%d",&k);
scanf("%d%d%d%d",&a,&x,&b,&y);
dp[0]=1;
for(int i=1; i<=x; i++) p[i]=a;
for(int i=x+1; i<=x+y; i++) p[i]=b;
for(int i=1; i<=x+y; i++) {
for(int j=k; j>=p[i]; j--)
dp[j]=(dp[j]%mod+dp[j-p[i]]%mod)%mod;
}
printf("%lld\n",dp[k]%mod);
return 0;
}
import java.util.*;
public class Main{
public static final int ASD = 1000000007;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int k=sc.nextInt();
int a=sc.nextInt(), x=sc.nextInt();
int b=sc.nextInt(), y=sc.nextInt();
int[] dp = new int[k+1];
dp[0] = 1;
for(int i=0; i<x ; i++){
for(int j=k; j>=a; j--){
dp[j] = (dp[j] + dp[j-a]) % ASD;
}
}
for(int i=0; i<y ; i++){
for(int j=k; j>=b; j--){
dp[j] = (dp[j] + dp[j-b]) % ASD;
}
}
System.out.println(dp[k]);
sc.close();
}
}
long long c[105][105];
const int mod = 1000000007;
void init()
{
c[0][0]=1;
for(int i=1;i<=100;i++){
c[i][0]=1;
for(int j=1;j<=100;j++){
c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod;
}
}
}
//小Q的歌单
#include<cstdio>
#include<iostream>
using namespace std;
long long c[105][105];
const int mod = 1000000007;
void init()
{ c[0][0]=1; for(int i=1;i<=100;i++){ c[i][0]=1; for(int j=1;j<=100;j++){ c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod; } }
}
int main()
{ int k,i,j,x,y,a,b; long long sum; init(); while(cin>>k>>a>>x>>b>>y){ sum = 0; if(a!=b){ for(i=0;i<=x;i++){ for(j=0;j<=y;j++){ if((i*a+j*b)>k) break; if((i*a+j*b)==k){ sum+=c[x][i]*c[y][j]; } } } } printf("%ld\n",sum%1000000007); } return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int totalLength = sc.nextInt();
int A = sc.nextInt();
int num_A = sc.nextInt();
int B = sc.nextInt();
int num_B = sc.nextInt();
int[] lengths = new int[num_A + num_B];
for (int i = 0; i < num_A; i++) {
lengths[i] = A;
}
for (int i = num_A; i < num_A + num_B; i++) {
lengths[i] = B;
}
int[][] dp = new int[totalLength + 1][num_A + num_B];
for (int j = 0; j < num_A + num_B; j++) {
dp[0][j] = 1;
}
for (int i = 1; i < totalLength + 1; i++) {
for (int j = 0; j < num_A + num_B; j++) {
if (j == 0) {
if (lengths[0] == i) dp[i][0] = 1;
} else {
dp[i][j] = dp[i][j - 1] + (lengths[j] <= i ? dp[i - lengths[j]][j - 1] : 0);
}
}
}
System.out.println(dp[totalLength][num_A + num_B - 1]);
}
}
感觉没那么复杂,分为两块,一块求策略集,另一块求排列组合,组合的公式直接套就行,杨辉三角感觉有点过了。本人渣渣python,C和Java之类的不太会
# coding:utf-8
# 小Q的歌单
def match(a, x, b, y, k):
get = []
for i in range(x + 1):
for j in range(y + 1):
if i * a + j * b == k:
get.append([i, j])
return get
def c(i, j):
a = 1
b = 1
tmp_i = i
tmp_j = j
while tmp_i >= 1:
a = a * tmp_j
b = b * tmp_i
tmp_i = tmp_i - 1
tmp_j = tmp_j - 1
return a / b
k = int(raw_input().strip())
# print(c(2,4))
[a, x, b, y] = [int(i) for i in raw_input().strip().split()]
get = match(a, x, b, y, k)
if len(get) == 0:
print 0
else:
result = 0
for i in get:
result = result + c(i[0], x) * c(i[1], y)
print result % 1000000007
//我来解释一下介个吧,自己理解的。
//对于K,如果从X个A中取出i个A之后的差刚好能够除以B,并且(K-A*i)/B结果小于B的个数Y的话,
// 那么就可以取。结果的个数为:组合C(X,i)*C(Y,(K-A*i)/B)
//此时算的C就是杨辉三角的计算方法。对于每一行n和每一列m来说,就是从n个中取出m个的组合个数。
public class songListxiaoQ {
public static void main(String[] args)
{
Scanner sr = new Scanner(System.in);
int K = sr.nextInt();
int A = sr.nextInt();
int X = sr.nextInt();
int B = sr.nextInt();
int Y = sr.nextInt();
int [][] c = new int[105][105];
c[0][0] = 1;
for(int i=1;i<=100;i++)
{
c[i][0] = 1;
for(int j=1;j<=100;j++)
{
c[i][j] = (c[i-1][j-1]+c[i-1][j])%1000000007;
}
}
int sum = 0;
for(int i=0;i<=X;i++)
{
if(i*A<=K&&(K-A*i)%B==0&&(K-A*i)/B<=Y)
sum = (sum+(c[X][i]*c[Y][(K-A*i)/B])%1000000007)%100000007;
}
System.out.println(sum);
}
}
//dp[i][j]表示总长度为i的歌单,使用前j首歌能组成的总数
k = int(input().strip())
lx, x, ly, y = list(map(int, input().strip().split(" ")))
dp = [1] + [0] * k # 第一位初始化为1
for i in range(x):
for j in range(k, lx-1, -1):
dp[j] += dp[j-lx]
for i in range(y):
for j in range(k, ly-1, -ly): # 第二次步长为ly
dp[j] += dp[j-ly]
print(dp[k]%1000000007) import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int length = scan.nextInt();
int A = scan.nextInt();
int X = scan.nextInt();
int B = scan.nextInt();
int Y = scan.nextInt();
System.out.println(qlist(length, A, X, B, Y));
}
public static long qlist(int length, int A, int X, int B, int Y) {
long mod = 1000000007;
// 构建杨辉三角
int max = 101;
long[][] tri = new long[max][max];
tri[0][0] = 1;
for (int i = 1; i < max; i++) {
tri[i][0] = 1;
for (int j = 1; j < max; j++) {
tri[i][j] = (tri[i - 1][j - 1] + tri[i - 1][j]) % mod;
}
}
long sum = 0;
for (int value = 0; value <= length; value++) {
if (value % A == 0 && (length - value) % B == 0 && value/A <= 100 && (length - value) / B <= 100) {
sum += tri[X][value / A] * tri[Y][(length - value) / B] % mod;
}
}
return sum % mod;
}
}
杨辉三角 ac
K=int(raw_input())
a,na,b,nb=map(int,raw_input().strip().split(' '))
arr=[a for i in range(na)]
brr=[b for j in range(nb)]
M=1000000007
def get_value(n):
if n==1:
return n
else:
return n * get_value(n-1)
def gen_last_value(n,m):
first = get_value(n)
second = get_value(m)
third = get_value((n-m)) if n!=m else 1
return first/(second * third) if n!=m else 1
ans=0
for i in range(na+1):
for j in range(nb+1):
if a*i+b*j==K:
if i!=0 and j!=0:
ans+=gen_last_value(na,i)*gen_last_value(nb,j)
elif i==0 and j==0:
ans+=0
else:
ans+=gen_last_value(na,i) if i!=0 else gen_last_value(nb,j)
print int(ans%M)
import sys def parse_nums(nums_str): return [int(x) for x in nums_str.strip().split()] # 基本输入输出 for s in sys.stdin: s = int(s) v1, n1, v2, n2 = parse_nums(input()) v = [v1] * n1 + [v2] * n2 n = n1 + n2 dp = [0] * (s + 1) dp[0] = 1 for i in range(n): for j in range(s, v[i] - 1, -1): dp[j] = (dp[j] + dp[j - v[i]]) % 1000000007 print(dp[s])
#include<iostream>
using namespace std;
#define mod 1000000007
long long arr[105][105];
void cal_c(){
arr[0][0] = 1;
for(int i = 1; i <= 100; ++i){
arr[i][0] = 1;
for(int j = 1; j <= i; ++j)
arr[i][j] = (arr[i-1][j] + arr[i-1][j-1]) % mod;
}
}
int main(){
int k,a,x,b,y;
long long ret = 0;
cin>>k>>a>>x>>b>>y;
cal_c();
for(int i = 0; i <= x; ++i)
for(int j = 0; j <= y; ++j){
if(a*i+b*j > k) break;
else if(a*i+b*j == k) ret = (ret + arr[x][i] * arr[y][j]) % mod;
}
cout<<ret;
return 0;
} # 组合数 C^(a)_(b) def cnn(a,b): if a == 0: return 1 fz,fm = 1,1 for i in range(a): fz *= (b-i) for i in range(a): fm *= (i+1) return fz//fm K = [int(x) for x in input().split()][0] A,X,B,Y = [int(x) for x in input().split()] # 组合方式, 即求解策略集 zhfs = [] a_max = min(K//A, X) b_max = min(K//B, Y) for a in range(a_max+1): b = 0 while a*A + b*B <= K and b <= b_max: if a*A + b*B == K: zhfs.append([a, b]) b += 1 ans = 0 if not zhfs: print(0) else: for i,j in zhfs: ans += (cnn(i,X)*cnn(j,Y)) print(ans%1000000007)python 3代码,本人计算机渣的一批,确实没看出来题目和杨辉三角的关系。。
# 动态规划,模仿背包问题,问题简化为有x+y种物品,其中x种的容积为a,y种的容积为b,背包容积为k,问背包装满一共有多少种解法?
# dp[i][j]: i 代表背包容积, j 代表前 j 个物品, 前 j 个元素恰填满容积为 i 的背包的组合数
k = int(input())
num_list = list(map(int, input().split()))
a, x, b, y = num_list[0], num_list[1], num_list[2], num_list[3]
things = [0] + [a for i in range(x)] + [b for i in range(y)] # 长度为 a+b+1
dp = [[0 for j in range(x+y+1)] for i in range(k+1)]
for i in range(x+y+1):
dp[0][i] = 1
# 考虑 i > 0
for i in range(1, k+1):
for j in range(1, x+y+1):
if things[j] > i:
dp[i][j] = dp[i][j-1]
elif things[j] == i:
dp[i][j] = dp[i][j-1] + 1
elif things[j] < i:
if dp[i-things[j]][j-1] != 0: #
dp[i][j] = dp[i][j-1] + dp[i-things[j]][j-1]
else:
dp[i][j] = dp[i][j-1]
print(int(dp[k][x+y])%1000000007) import sysif __name__ == "__main__":data=[]while True:line = sys.stdin.readline().strip()if not line:breaktmp = list(map(int, line.split(" ")))data.append(tmp)n=data[0][0]l=data[1]length=[0]for i in range(l[1]):length.append(l[0])for i in range(l[-1]):length.append(l[-2])def gedan(n,length):dp=[[0 for i in range(len(length))]for i in range(n+1)]for i in range(5):dp[0][i]=1for j in range(1,n+1):dp[j][0]=0for i in range(1,n+1):for j in range(1,len(length)):if length[j] > i:dp[i][j] = dp[i][j-1]elif length[j] == i:dp[i][j]=dp[i][j-1]+1else:dp[i][j] = dp[i][j-1]+dp[i-length[j]][j-1]return dp[n][len(length)-1]%1000000007print(gedan(n,length))
''' import itertools K = int(input()) A,X,B,Y = input().split() A,X,B,Y = int(A), int(X), int(B), int(Y) result = 0 list_X = list(range(X)) list_Y = list(range(Y)) for x in range(X+1): for y in range(Y+1): k = A * x + B * y if k == K: print("%d = %d * %d + %d * %d"%(k, A, x, B, y)) result_X = list(itertools.combinations(list_X, x)) result_Y = list(itertools.combinations(list_Y, y)) print(result_X) print(result_Y) result += len(result_X) * len(result_Y) result = result % 1000000007 print(result) ''' import math def C(n,m): m1 = m m2 = m uper = 1 downer = 1 while(m1>0): uper *= n m1 -= 1 n -= 1 while(m2>0): downer *= m2 m2 -= 1 return int(uper/downer) K = int(input()) A, X, B, Y = map(int, input().strip().split(' ')) result = 0 for x in range(X+1): for y in range(Y+1): k = A * x + B * y if k == K: print(x,y) result += C(X,x) * C(Y,y) result = result % 1000000007 print(result)
链接:https://www.nowcoder.com/questionTerminal/f3ab6fe72af34b71a2fd1d83304cbbb3
来源:牛客网
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为70.00%
测试用例:
205
1 92 4 92
对应输出应该为:
580636981
你的输出为:
162025174
这是什么原因?
print(sum%1000000007)
public class SongSheetForQ {
public static long[][] arr = new long[101][101];
public static long constituteMethod(int K, int A, int X, int B, int Y){
long result = 0;
int length;
arr[0][0] = 1;
for (int i = 1; i <= 100; i++){
arr[i][0] = 1;
for (int j = 1; j <= 100; j++) {
arr[i][j] = (arr[i - 1][j] + arr[i - 1][j - 1]) % 1000000007;
}
}
for (int i = 0; i <= X; i++){
length = K - A * i;
if (length >= 0 && length % B == 0 && length / B <= Y){
result += (arr[X][i] * arr[Y][length / B]);
}
}
return result % 1000000007;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int K = sc.nextInt();
int A = sc.nextInt();
int X = sc.nextInt();
int B = sc.nextInt();
int Y = sc.nextInt();
sc.close();
System.out.println(constituteMethod(K, A, X, B, Y));
}
}
#include<iostream>
#include<stdlib.h>
#include <math.h>
using namespace std;
const int mod=1000000007;
int main()
{
int i, j, K, la, lb, na, nb,result;
cin >> K;
cin >> la >> na >> lb >> nb; //输入的信息
int *lens=new int[na+nb+1]; //建立动态数组lens[j]表达第j首歌长度
for(i=1;i<=na;i++){
lens[i]=la;
}
for(i=1;i<=nb;i++){
lens[i+na]=lb;
} //将na,nb数量的歌的长度按顺序存储进数组lens
int **db=new int*[K+1]; //建立二维动态数组db[i][j]存储j首歌组成长度为i的方法
for(int i=0;i<K+1;i++){
db[i]=new int[na+nb+1];
} //为二维数组申请内存
for(int j=1;j<na+nb+1;j++){
db[0][j]=1;
} //所有j首歌组成长度为0的方法为1
for(int i=1;i<K+1;i++){
if(lens[1]!=i){
db[i][1]=0;
}
else
db[i][1]=1;
} //用1首歌组成长度为i的方法根据长度判断
for(i=1;i<K+1;i++){
for(j=2;j<na+nb+1;j++){
if(i>=lens[j])
db[i][j]=(db[i][j-1]+db[i-lens[j]][j-1])%mod;
else db[i][j]=db[i][j-1]%mod;
}
}
//当i的长度大于等于第j首歌长度时,用j首歌组成长度为i的方法分两部分,1部分为用j-1首歌组成长度为i的歌单
//另一部分为由j-1首歌组成长度为i-lens[j]的歌单,因为第j首歌长度恰好为lens[j]
cout<<db[K][na+nb]<<endl; //输出最后由na+nb首歌组成长度为K的歌单的方法总数
system("pause");
return 0;
}