题意:
给出一个二进制形式的重量的物品,现在有n个砝码分别是2^0、2^1....2^(n-1)。现在问如何在天平上放砝码可以使得天平平衡。
题解:
我们分析,假设我们左边放的砝码重量总和为x,右边放的重量总和为y(左边还有放物品)。
那么问题就转化重量为w的物品加砝码能变成那些可行重量的问题。我们根据物品的重量的二进制来求解,按位dp。dp[i][2],0表示进位,1表示不进位。这样分两个大类来考虑:
1、这一位是'0'
(1)这位不进位dp[i][0]=dp[i-1][0]+dp[i-1][1]
(2)这位进位dp[i][1]=dp[i-1][1]
2、这一位是'1'
(1)这位不进位dp[i][0]=dp[i-1][0]
(2)这位进位dp[i][1]=dp[i-1][0]+dp[i-1][1]
状态方程要好好思考,不多做解释。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
void cmax(int& a,int b){ if(b>a)a=b; }
void cmin(int& a,int b){ if(b<a)a=b; }
void cmax(ll& a,ll b){ if(b>a)a=b; }
void cmin(ll& a,ll b){ if(b<a)a=b; }
void add(int& a,int b,int mod){ a=(a+b)%mod; }
void add(ll& a,ll b,ll mod){ a=(a+b)%mod; }
const int oo=0x3f3f3f3f;
const int MOD=1000000007;
const int maxn=5100;
const int maxm=21000;
ll dp[1000005][2];
char bit[1000005];
int main(){
//freopen("E:\\read.txt","r",stdin);
int n,l,d,T;
scanf("%d",&T);
while(T--){
scanf("%d %d %d",&n,&l,&d);
scanf("%s",bit+1);
for(int i=1;i<=l/2;i++)
swap(bit[i],bit[l-i+1]);
for(int i=l+1;i<=n;i++)
bit[i]='0';
memset(dp,0,sizeof dp);
dp[0][0]=1;
for(int i=1;i<=n;i++){
if(bit[i]=='0'){
add(dp[i][0],dp[i-1][0]+dp[i-1][1],d);
add(dp[i][1],dp[i-1][1],d);
}else{
add(dp[i][0],dp[i-1][0],d);
add(dp[i][1],dp[i-1][0]+dp[i-1][1],d);
}
}
printf("%I64d\n",dp[n][0]);
}
return 0;
}