HDU 5119 Happy Matt Friends(DP)

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

你可能感兴趣的:(动态规划,ACM-ICPC)