[usaco3.2.2]kimbits

  这道题又是看了题解。

  思想大概是:我们枚举到i位数有j个1,用杨辉三角形求组合数,第i行第j列就是C(i-1,j-1),用sum[i][j]表示i位数0..j个1的所有的数的个数,那么sum[i][j]=C(i,0)+C(i,1)+......+C(i,j),那么当我们求第k个数时,当sum[i-1][j](i-1位数,0...j个1的方案数)<k时,意味着第i位是1,否则是0,以此类推。

/*
ID:abc31261
LANG:C++
TASK:kimbits
*/

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=50;
long long sum,f[maxn][maxn],n,k,l;
int main()
{
    int i,j;
    freopen("kimbits.in","r",stdin);
    freopen("kimbits.out","w",stdout);
    cin>>n>>l>>k;
    f[0][0]=1;
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)f[i][j]=f[i-1][j-1]+f[i-1][j];//杨辉三角形
    for (i=n;i>=1;i--)
    {
        if (l==0)printf("0");
        else
        {
            sum=0;
            for (j=1;j<=l+1;j++)sum+=f[i][j];           //杨辉三角形从1开始的话第i行第j列是C(i-1,j-1);
            if (sum>=k)printf("0");
            else
            {
                printf("1");
                k-=sum;                                 //减去第i位是0的方案数
                l--;
            }
        }
    }
    cout<<endl;
    return 0;
}
时间: 2024-12-19 14:44:27

[usaco3.2.2]kimbits的相关文章

usaco-3.1-PROB Shaping Regions-漂浮法

漂浮法,顾名思义,就是一块块的往上飘. 以逆序来进行放置,即n to 1.逆序的好处在于放置一个矩形后,俯视看到的就是最终俯视该矩形应该看到的.因为挡着它的矩形在之前已经放置好了,所以可直接统计,为递归创造了条件.每放一个矩形,可以想象成将其扔入一密度很大的海水底部,海分成了n层,然后矩形开始向上浮.在上浮过程中若碰撞到其他的矩形则断裂成几个小矩形,继续上浮,直到浮出水面.于是想到用个递归来模拟上浮过程. /* ID: rowanha3 LANG: C++ TASK: rect1 */ #inc

USACO 3.2 kimbits DP

自己YY了个DP:设f[n][l]为n位数中包含不超过l个1的总个数 f[n][l]=f[n-1][l]+f[n-1][l-1] 然后用_search()从高位向低位扫描即可,tmp记录当前已记下多少个数了(这些数肯定都比第I个小) 一开始f数组的初值YY错了,看了nocow改过来就好了 1 /* 2 PROB:kimbits 3 LANG:C++ 4 */ 5 #include <stdio.h> 6 #include <cstring> 7 int N,L,tmp; 8 lon

usaco-3.2-kimbits-pass

就这个比较清晰: /* ID: qq104801 LANG: C++ TASK: kimbits */ #include <iostream> #include <fstream> #include <cstring> #include <vector> #include <map> #include <list> #include <set> #include <queue> #include <cst

USACO--3.1Stringsobits

开始的时候暴力了一次,但是在第10个点就超时了.后面才知道这个题实际上是一个组合数的题目.在每个位置我们可以选择放0或者1,并且我们可以统计出每种放法后面数的排列数,然后我们可以决定放0或放1,继续这个过程直到最后. 所以重点是计算出dp[i][j],表示i位中至多有j位1.对这个我们可以采用dp的方法来求dp[i][j]=dp[i-1][j]+dp[i-1][j-1]; 也可以使用组合数来求dp[i][j]=c[i][0]+c[i][1]+-+c[i][j] 代码如下: /* ID: 1567

[usaco3.2.3]spin

这道题直接枚举就好了,但我当时竟然没想到,我真是太失败了.....Q_Q /* ID:abc31261 LANG:C++ TASK:spin */ #include<cstdio> #include<cstring> #include<iostream> using namespace std; const int n=5,maxn=360; int s[10],first[10][10],end[10][10],num[10],f[maxn*2]; bool flag

[usaco3.2.5]msquare

题目传送门:http://www.nocow.cn/index.php/Translate:USACO/msquare 这道题bfs+hash,但想到要判重的数字不多,就直接用了map,数组传递有些麻烦,所以直接写在了一起,会有点乱 /* ID:abc31261 LANG:C++ TASK:msquare */ #include<cstdio> #include<cstring> #include<queue> #include<map> #include&

USACO--3.2Sweet Butter+推优化的Dijkstral算法

这个题目思路是很简单的,我们只需要枚举每个顶点作为目的地,然后再取其中距离总和最小的作为答案.开始的时候我用的是floyd一次就将所有点之间的最小距离求出来,但是超时了. 后面每次枚举一个点就用堆优化的dijkstral求一次这个点到其余点的最短路,这样就可以过了.算法中还用数组模拟了图的邻接矩阵. 代码如下: /* ID: 15674811 LANG: C++ TASK: butter */ #include<iostream> #include<cstdio> #include

usaco-3.4-rockers-passed

又是一个背包问题,动态规划求解: /* ID: qq104801 LANG: C++ TASK: rockers */ #include <iostream> #include <fstream> #include <cstring> #include <vector> #include <queue> #include <stack> #include <algorithm> using namespace std; #

[USACO3.3.3]camelot

题目传送门:http://www.nocow.cn/index.php/Translate:USACO/camelot 这道题让我心痛,一开始写写不出,后来拖了很久,决定去看题解,没想到又看不懂官方题解,唉!后来看了下面的题解做了出来.题解的话,大概就是先预处理每个格子到另外格子的位置,再枚举在王的坐标+-2位置接王,枚举所有棋子的集中点加起来计算就好了.我的代码为了方便略粗鲁. 题解传送门:http://www.nocow.cn/index.php/USACO/camelot /* ID:ab