[51Nod 1301] 集合異或和 (dp)
阿新 • • 發佈:2018-09-07
question memset const cstring std 情況 .com 背包 比較
傳送門
Solution
一道比較好的dp題 想了半天組合數QAQ
首先要知道的是 A<B一定是B有一位是1且A的這位是0且前面都相等
那麽肯定是要枚舉這一位在哪裏然後求出方案數
方案數考慮類似背包的方法分三種情況轉移具體見代碼
Code
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define F(i,a,b) for(register int i=(a);i<=(b);i++) using namespace std; typedef long long LL; const int N=5000,MOD=1e9+7; int n,m; LL ans,f[2][N][2]; int main() { cin>>n>>m; for(int i=0;(1<<i)<=max(n,m);i++) { memset(f,0,sizeof(f)); f[0][0][0]=1; for(int j=1;j<=max(n,m);j++) { int x=(j>>i)&1,c=j&1; for(int k=0;k<=2048;k++) F(X,0,1) { f[c][k][X]=f[c^1][k][X]; if(j<=n) f[c][k][X]=(f[c][k][X]+f[c^1][k^j][X])%MOD; if(j<=m) f[c][k][X]=(f[c][k][X]+f[c^1][k^j][X^x])%MOD; } } F(j,(1<<i),(1<<(i+1))-1) ans=(ans+f[(max(n,m)&1)][j][1])%MOD; } printf("%lld",ans%MOD); return 0; }
[51Nod 1301] 集合異或和 (dp)