問題P2727シリーズStringsobitsに羅区の溶液[01]

このこんにゃくは、Liは、スパイシーなステップ二重のチーズを爆破されています!

P2727 01串Stringsobits

実際には、限り理解が思うだろうとして、これはあります吸盤のタイトル

このトピックとラベルがdp、検索、数論であります

しかし、あなたは半分を行うためのアイデアを使用することができます!

溶液:

彼は、最上位ビットを列挙し始め、

我々は唯一の0/1を取ることができていない、一人一人を考えます

そして、私たちが最初にこのビットが0に設定されているときに見つけ、それはプログラムの数を行うことができます(そしてなぜ要件を教えてくれます

私たちは、このビットはこのビットが1であるとき、0であるときことを、と思いますか?

私たちは、そのプログラム番号、このプログラムはそれがありませんが、このビットは0を達成することができていることを最大の番号を見つけます。

私は、この最大値よりも大きい場合、このビットは0がちょうどそれをしないではないです。

結果:

このプログラムは、番号iよりも大きい場合には最高のビット数がゼロの間でそう、私は、特定の数のランクを説明し、それ以外の場合は、最上位ビットに属する数1です。

あなたはそれを下に検討する少しずつ!

これは、それを解決する、バイナリ思考の使用です。

プログラムの数は、その行に始まるDPで再び実行し、

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

それはかつての0/1の値に加算しています。

コード:

#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;
}

ここで私はワシントン州の前にそれが二回言いました

最初:

エラー1

私は実行を開始しないように0番から、和[] []の時間を祈ります。

第二:

エラー2

長いlongQAQを開けませんでした

シモンズ:してください再読み込みコピー

おすすめ

転載: www.cnblogs.com/Flash-plus/p/12028272.html