https://codeforces.com/problemset/problem/65/D
哈利波特!一种新思路的状压记忆化dfs,记得每次dfs用完要减回去。而且一定是要在dfs外部进行加减!防止在中间return的时候忘记弄回来。用哈希记录状态实现真正的记忆化。
#include<bits/stdc++.h> using namespace std; #define ll long long int n; char s[10005]; ll getID(int a[]){ ll res=0; for(int i=0;i<4;i++){ res=res*10000+a[i]; } return res; } int a[4]={}; int c[4]={}; set<ll> se; int dfs(int i){ ll ID=getID(a); if(se.count(ID)) return 0; else{ se.insert(ID); //printf("%d-%lld\n",i,ID); if(i==n){ int minnum=*min_element(a,a+4); for(int j=0;j<4;j++){ if(a[j]==minnum){ c[j]=1; } } return 0; } } if(s[i]!='?'){ switch (s[i]){ case 'G': a[0]++; dfs(i+1); a[0]--; break; case 'H': a[1]++; dfs(i+1); a[1]--; break; case 'R': a[2]++; dfs(i+1); a[2]--; break; case 'S': a[3]++; dfs(i+1); a[3]--; } } else{ int minnum=*min_element(a,a+4); for(int j=0;j<4;j++){ if(a[j]==minnum){ //cout<<"j="<<j<<endl; a[j]++; dfs(i+1); a[j]--; } } } } int main(){ scanf("%d",&n); scanf("%s",s); dfs(0); //printf("%d\n",se.size()); if(c[0]) puts("Gryffindor"); if(c[1]) puts("Hufflepuff"); if(c[2]) puts("Ravenclaw"); if(c[3]) puts("Slytherin"); }