小Q的歌单

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

解法一(参考自牛客网ID为 我是牛我是牛牛 的代码(带有笔者自己写的解析)):

看作是01背包问题

#include<iostream>
using namespace std;
int B[201][1001]={0};   // B[i][j],歌单剩余长度为j,用来取1-i首歌的最多方案数
int w[201];   //w[i] :第i首歌占用的长度


int main(){
    int k,a,x,b,y,i,j;
   while(cin>>k){
        cin>>a>>x>>b>>y;
        for(i=0;i<=x+y;i++){
        	B[i][0]=1;  //B[i][0]都为1,意思是只要歌单长度为0,就算是1种方案。
		}
        
        for(i=1;i<=x;i++){
            w[i]=a;
        }
        for(i=x+1;i<=x+y;i++ ){
            w[i]=b;
        }
        for(i=1;i<=x+y;i++){
            for(j=1;j<=k;j++){
        /*  当当前所剩的长度>=歌曲i的长度时(忽略掉%1000000007)
				(当有i首歌 剩余长度为j 的方案总数)=不取这首歌的(即有i-1首歌 剩余长度为j的方案总数)+ 取这首歌(即有i-1首歌 剩余长度为j-这首歌长度p[i]的方案总数)
			否则(这首歌的长度已经超过歌单剩余长度了)
				(当有i首歌 剩余长度为j 的方案总数)=不取这首歌的(即有i-1首歌 剩余长度为j的方案总数) */
                if(j>=w[i])
                    B[i][j]=(B[i-1][j-w[i]]%1000000007+B[i-1][j]%1000000007)%1000000007;
                else
                    B[i][j]=B[i-1][j];
            }
        }
        cout<<B[x+y][k]<<endl; //B[x+y][k]就是当歌单长度为k,有x+y首歌时的最多方案数
    }
}

————————————————
原文链接:https://blog.csdn.net/jmasker/article/details/86842035

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值