문제 P2727 시리즈 Stringsobits 루오로 구 용액 [01]

이 곤약은 리튬 매운 강화 이중 치즈 발파되었습니다!

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

I는 게재하지 번호 0, 합계 [] [] 시간기도한다. . .

둘째:

오류 2

오래 안 열려 longQAQ

추신:제발 다시 읽어 사본

추천

출처www.cnblogs.com/Flash-plus/p/12028272.html