Luo Gu solution to a problem P2727 series Stringsobits [01]

This Konjac has been blasting the dual Cheese Li stepped spicy!

P2727 01串 Stringsobits

In fact, as long as the understanding will think this is aSucker title

This topic and the label is dp, search, number theory

But you can use the idea of ​​doing half!

Solution:

He began to enumerate the most significant bit,

We consider every one, is not only can take 0/1

Then we first find when this bit is set to 0, it can be done a number of programs (and so will tell you why requirements

We think, that when this bit is 0, when this bit that is 1? ? ?

We find out its program number, the maximum number that this program is not that, but this bit is 0 can be achieved;

If i is larger than this maximum, then this bit is 0 is not just not do that.

result:

So, if this program is larger than the number i, i explain certain number ranks among the highest bit number is zero, otherwise it belongs to the most significant bit is number 1.

Bit by bit you consider down on it!

This is the use of binary thinking, solving it.

As the number of programs, then run again in the beginning dp on the line,

g[i][j] = g[i - 1][j - 1] + g[i - 1][j];

It is adding to the value of 0/1 of the former.

code:

#include<bits/stdc++.h>//万能头

using namespace std;

#define maxn 60//可以稍微大一点 
#define int long long//这是个坑 
#define Rep(x, a, b) for(int x = a; x <= b; ++ x)
#define Dep(x, a, b) for(int x = a; x >= b; -- x)

int n, l, k, g[maxn][maxn], sum[maxn][maxn], a[maxn];
//g[k][i]是来表示在前k位中,恰有i个1的二进制数的数量
//sum[k][i]是来表示在前k位中,最多有i个1的二进制数的数量
//a[i]是当前这一位是0/1,输出是用。

void dfs(int x, int l, int k){
if(x == 0){//跑到了最后一位了 
Dep(i, n, 1){//输出路径 
printf("%d", a[i]);
}
exit(0);//不可以用return,return只结束当前这一轮函数,exit(0)就可以直接结束程序。 
}
if(k <= sum[x - 1][l]){//如果它小于或等于此位取0时的最大值 
a[x] = 0;//当前这位就取0; 
dfs(x - 1, l, k);//并且直接跑到下一位 
}
else{//如果它大于的话 
a[x] = 1;//当前就取1; 
dfs(x - 1, l - 1, k - sum[x - 1][l]);//并且跑下一位的时候要把还可以取的‘1’的数量-1,然后要跑的数位也会减去这位取了‘1’以后减下的值。 
}
}

signed main(){
scanf("%d%d%d", &n, &l, &k);//RT 
g[0][0] = 1;//初始化,一定要记得 
Rep(i, 1, n){
g[i][0] = 1;//如果只要0个‘1’,肯定只有1种方法。 
Rep(j, 1, n){
g[i][j] = g[i - 1][j - 1] + g[i - 1][j];//递归求恰有i个1的二进制数的数量
}
}
Rep(i, 0, n){
Rep(j, 0, n){
Rep(k, 0, j){
sum[i][j] += g[i][k];//跑一下求最多有i个1的二进制数的数量
}
}
}
dfs(n, l, k);//搜索一下就可以了 
return 0;
}

Here what I said that twice before in Wa

First:

Error 1

I pray sum [] [] time, not from No. 0 to start running. . .

Second:

Error 2

Did not open long longQAQ

Ps:Please re-read copy

Guess you like

Origin www.cnblogs.com/Flash-plus/p/12028272.html