SOJ Binary Numbers dp + 逼近思想

题意:给定k(k<=10000000)和n(n<=10),问在由n个1组成的二进制数中第k大的数的二进制是什么。

题解:看到题就想到是构造,由于问的是第k大,那么逐步逼近。

         预处理出dp[ i ][ j ][ 0 ]表示末 i 位中有 j 个1且当前位为0的方法数,dp[ i ][ j ][ 1 ]表示末 i 位中有 j 个1且当前位为1的方法数,

         然后从高位到低位扫一遍即可。但是由于n = 1的时候可以直接得到答案,所以n = 2为极限情况,所以预处理到4500即可。


Sure原创,转载请注明出处

#include 
#include 
#include 
#include 
#include 
#define MIN(a , b) ((a) < (b) ? (a) : (b))
using namespace std;
const int maxn = 4500;
int dp[maxn][12][2],ans[maxn];
int n,m;

void init()
{
    memset(dp,0,sizeof(dp));
    dp[1][1][1] = dp[1][0][0] = 1;
    for(int i=2;i=1 && n;i--)
    {
        if((dp[i][n][0] != -1 && dp[i][n][0] < m) || i == n)
        {
            ans[maxn-i] = 1;
            m -= dp[i][n][0];
            n--;
        }
        else ans[maxn-i] = 0;
    }
    int i=1;
    for(;i

你可能感兴趣的:(SOJ Binary Numbers dp + 逼近思想)