2016.9.26测试解题报告(KFC)--二进制+组合数

Description:

最近Kfc新开了个KFC,该KFC提供N种食物,分别用1-N给这些食物编号,食物的价格与其编号有关,满足第K种食物的价格为2^(K-1),例如:

食物的编号 1 2 3 4 5 6 7 8 9 10……

价格 1 2 4 8 16 32 64 128 256 512 ……

每位顾客最多可以选择L种食物,且每种食物仅一份。

当顾客选择食物时,他会说:我要第M便宜的食物组合。

Kfc的工作就是计算第该食物组合的价格。

一样食物都不要也是一种组合,因此第1便宜的食物组合价格为0。


Input:

一行,包含三个整数N (1<=N<=30),,L (1<=L<=N),M,用一个空格隔开。数据保证存在第M便宜的食品组合。


Output:

一行,包含一个整数P,P为第M便宜的食品组合的价格。


Sample Input

5 3 19

Sample Output

19

题目分析:

显然的二进制+组合数。用一种食物来代表二进制中的一位。逐位确定二进制数,求解。


代码:

/*
2016.9.26 BulaBulaCHN
*/
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#define min(a,b) ((a)<(b)?(a):(b))
#define min(a,b) ((a)>(b)?(a):(b))
using namespace std;
int l,n,m;
int cc[30][30];
int ans;
int c(int n,int m)
{
    if(n==0) return 1;
    if(m==0) return 1;
    if(m==1) return n;
    if(m==n) return 1;
    if(cc[n-1][m-1] && cc[n-1][m]) return cc[n][m]=cc[n-1][m-1]+cc[n-1][m];
    if(cc[n][m]) return cc[n][m];
    return cc[n][m]=c(n-1,m-1)+c(n-1,m);
}
int main()
{
    freopen("kfc.in","r",stdin);
    freopen("kfc.out","w",stdout);
    scanf("%d%d%d",&n,&l,&m);
    if(m==1) {cout<<0; return 0;}
    int last=l;
    int lnum=m-1; //应在答案的数字之前的商品组合的个数
    int sum=1;
    while(1)
    {
        int flag=1;
        sum=1;
        for(int pos=0;pos<=n;pos++)
        {
            int f=0;
            for(int i=0;i<=min(last-1,pos-1);i++) f+=c(pos-1,i); //计算最高位为pos位时的方案数
            if(sum+f>lnum) {flag=pos; break;}
            if(sum+f==lnum) {sum+=f; flag=pos+1; break;} //特殊处理取最后一位
            sum+=f;
        }
        ans|=(1<<(flag-1)); //统计答案
        lnum-=sum;
        last--;
        if(lnum==0) break; //找到了所有应在答案之前的数字
    }
    cout<<ans<<endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值