求解方案数的简单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;
}

本文讨论了一种使用动态规划(DP)解决特定问题的方法。在比赛中,作者未能将问题视为典型的背包问题,导致思维受限。通过记忆化搜索实现DP算法,尽管效率较低且占用内存,但提供了易于理解的解决方案。文章提供了详细的代码实现,包括如何将其转换为递推式和滚动数组形式,以优化性能。

被折叠的 条评论
为什么被折叠?



