给出一个二进制数的位数为N位(N < 100),二进制数的值是多少不确定,给定一个数 Y (Y < 100) , 使得从左边起,第一位 * 第二位 + 第二位 * 第三位 + 第三位 * 第四位 …… + 第 N - 1 位 * 第 N 位 = Y 成立 ,求出满足等式的二进制数有多少个;
下面给出我的思考过程:
由于 N 和 Y 都是不确定的,并且二进制数的最后一位是 0 或 1 ,所以假设 dp[ i ][ j ][ 0 ] 代表 Y = i , N = j , 即 二进制的位数为 j , 给定的数为 i ,且第 N 位 为 0 ,满足条件的二进制数的个数; dp[ i ][ j ][ 1 ] 代表 Y = i , N = j ,即二进制的位数为 j , 给定的数为 i ,且第 N 位 为 1 ,满足条件的二进制的个数 ;
首先将数组dp赋初始值为: 0 , dp[100][100][2] = {0} ;
假设二进制数只有一位,则 :
dp[ 0 ][ 1 ][ 0 ] = 1 ;
dp[ 0 ][ 1 ][ 1 ] = 1 ;
给定的值从1开始到100,每一个给定的值都对应二进制的位数从2到100 ;
给定值为 0 时,dp[ 0 ][ 2 ][ 0 ] = dp[ 0 ][ 1 ][ 0 ] + dp[ 0 ][ 1 ][ 1 ]
dp[ 0 ][ 2 ][ 1 ] = dp[ 0 ][ 1 ][ 0 ]
dp[ 0 ][ 3 ][ 0 ] = dp[ 0 ][ 2 ][ 0 ] + dp[ 0 ][ 2 ][ 1 ]
dp[ 0 ][ 3 ][ 1 ] = dp[ 0 ][ 2 ][ 0 ]
………………
dp[ 0 ][ 100 ][ 0 ] = dp[ 0 ][ 99 ][ 0 ] + dp[ 0 ][ 99 ][ 1 ]
dp[ 0 ][ 100 ][ 1 ] = dp[ 0 ][ 99 ][ 0 ]
给定值为 1 时,dp[ 1 ][ 2 ][ 0 ] = dp[ 1 ][ 1 ][ 0 ] + dp[ 1 ][ 1 ][ 1 ]
dp[ 1 ][ 2 ][ 1 ] = dp[ 1 ][ 1 ][ 0 ] + dp[ 0 ][ 1 ][ 1 ]
dp[ 1 ][ 3 ][ 0 ] = dp[ 1 ][ 2 ][ 0 ] + dp[ 1 ][ 2 ][ 1 ]
dp[ 1 ][ 3 ][ 1 ] = dp[ 1 ][ 2 ][ 0 ] + dp[ 0 ][ 2 ][ 1 ]
……………………
dp[ 1 ][ 100 ][ 0 ] = dp[ 1 ][ 99 ][ 0 ] + dp[ 1 ][ 99 ][ 1 ]
dp[ 1 ][ 100 ][ 1 ] = dp[ 1 ][ 99 ][ 0 ] + dp[ 0 ][ 99 ][ 1 ]
给定值为 2 时,dp[ 2 ][ 2 ][ 0 ] = dp[ 2 ][ 1 ][ 0 ] + dp[ 2 ][ 1 ][ 1 ]
dp[ 2 ][ 2 ][ 1 ] = dp[ 2 ][ 1 ][ 0 ] + dp[ 1 ][ 1 ][ 1 ]
dp[ 2 ][ 3 ][ 0 ] = dp[ 2 ][ 2 ][ 0 ] + dp[ 2 ][ 2 ][ 1 ]
dp[ 2 ][ 3 ][ 1 ] = dp[ 2 ][ 2 ][ 0 ] + dp[ 1 ][ 2 ][ 1 ]
……………………
dp[ 2 ][ 100 ][ 0 ] = dp[ 2 ][ 99 ][ 0 ] + dp[ 2 ][ 99 ][ 1 ]
dp[ 2 ][ 100 ][ 1 ] = dp[ 2 ][ 99 ][ 0 ] + dp[ 1 ][ 99 ][ 1 ]
………………
给定值为100时,dp[ 100 ][ 2 ][ 0 ] = dp[ 100 ][ 1 ][ 0 ] + dp[ 100 ][ 1 ][ 1 ]
dp[ 100 ][ 2 ][ 1 ] = dp[ 100 ][ 1 ][ 0 ] + dp[ 99 ][ 1 ][ 1 ]
dp[ 100 ][ 3 ][ 0 ] = dp[ 100 ][ 2 ][ 0 ] + dp[ 100 ][ 2 ][ 1 ]
dp[ 100 ][ 3 ][ 1 ] = dp[ 100 ][ 2 ][ 0 ] + dp[ 99 ][ 2 ][ 1 ]
……………………
dp[ 100 ][ 100 ][ 0 ] = dp[ 100 ][ 99 ][ 0 ] + dp[ 100 ][ 99 ][ 1 ]
dp[ 100 ][ 100 ][ 1 ] = dp[ 100 ][ 99 ][ 0 ] + dp[ 99 ][ 99 ][ 1 ]
当输入N 和 Y 时 , 输出dp[ Y ][ N ][ 0 ] + dp[ Y ][ N ][ 1 ] 即为二进制数的个数;
下面给出相应思路的代码:
#include<iostream>
using namespace std ;
int main() {
int i ;
int dp[110][110][2] = {0} ;
dp[0][1][0] = 1 ;
dp[0][1][1] = 1 ;
for(i = 2 ; i <= 100 ; i++) {
dp[0][i][0] = dp[0][i-1][0] + dp[0][i-1][1] ;
dp[0][i][1] = dp[0][i-1][0] ;
}
for(i = 1 ; i <= 100 ; i++)
for(int j = 2 ; j <= 100 ; j++) {
dp[i][j][0] = dp[i][j-1][0] + dp[i][j-1][1] ;
dp[i][j][1] = dp[i][j-1][0] + dp[i-1][j-1][1] ;
}
int N ;
cin >> N ;
while(N--) {
int n , y ;
cin >> n >> y ;
cout << dp[y][n][0] + dp[y][n][1] << endl ;
}
return 0 ;
}