题意:
给出一个二进制形式的重量的物品,现在有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; }