求解方案数的简单DP,比赛时没有往DP上想,思维比较局限。
状态转移很好写,类似于背包,我用记忆化搜索写的容易写,但是效率比较低,还占内存,读者可以改成递推式,还可以改成滚动数组,因为每一层的状态只用到它上一层的状态 。
细节参见代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<list> #include<cmath> #include<set> #include<queue> using namespace std; typedef long long ll; const int INF = 100000000; const long long maxn = 100 + 5; int T,n,m,kase = 0,vis[41][(1<<20)+5],a[maxn]; ll d[41][(1<<20)+5]; ll dp(int i,int j) { if(i == n+1 && j >= m) return 1; if(i == n+1 && j < m) return 0; ll& ans = d[i][j]; if(vis[i][j] == kase) return ans; vis[i][j] = kase; ans = 0; ans = dp(i+1,j^a[i]) + dp(i+1,j); return ans; } int main() { scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); ++kase; printf("Case #%d: %I64d\n",kase,dp(1,0)); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-25 08:27:46