這題暴力複雜度是O(2^n)的,對於24的複雜度明顯不可做,我的方法是進行最佳化,枚舉前n/2個,得到每個陷阱對應的寶物編號,這樣對應了一個映射,然後枚舉剩下的寶物,找到對應陷阱所對應的前半部分寶物,所有寶物的價值之和就是目前的答案,取最大的即可。
寶物和陷阱可以用int和long long壓縮,最後放入map中。複雜度O(2^(n/2))
My Code:
#include <cstring><br />#include <cstdio><br />#include <cstdlib><br />#include <vector><br />#include <map><br />#include <algorithm></p><p>using namespace std;</p><p>vector<int> trap[25];<br />int v[25];<br />int n,maxd;<br />map<long long,vector<int> > mp;<br />int ret;</p><p>void run(int st,long long val){<br />int ans,nst;<br />vector<int> part;</p><p>if(mp.find(val)==mp.end())<br />return;<br />part=mp[val];<br />int m=part.size();<br />for(int k=0;k<m;k++){<br />nst=st|part[k];<br />ans=0;<br />for(int i=0;i<n;i++){<br />if(nst&(1<<i)){<br />ans+=v[i];<br />}<br />}<br />if(ans>ret)<br />ret=ans;<br />}<br />}</p><p>void dfs(int k,int st,long long val){<br />int nst;<br />long long nval;</p><p>if(k==maxd){<br />if(mp.find(val)==mp.end()){<br />vector<int> v;<br />v.push_back(st);<br />mp[val]=v;<br />}else{<br />mp[val].push_back(st);<br />}<br />return;<br />}</p><p>int m=trap[k].size();<br />dfs(k+1,st,val);<br />nst=st;<br />nval=0;<br />nst|=(1<<k);<br />for(int i=0;i<m;i++){<br />nval|=(1ll<<trap[k][i]);<br />}<br />dfs(k+1,nst,val^nval);<br />}</p><p>void dfs2(int k,int st,long long val){<br />int nst;<br />long long nval;</p><p>if(k==n){<br />run(st,val);<br />return;<br />}</p><p>int m=trap[k].size();<br />dfs2(k+1,st,val);<br />nst=st;<br />nval=0;<br />nst|=(1<<k);<br />for(int i=0;i<m;i++){<br />nval|=(1ll<<trap[k][i]);<br />}<br />dfs2(k+1,nst,val^nval);<br />}</p><p>int main(){<br />int m,x;</p><p>while(~scanf("%d",&n)){<br />mp.clear();<br />ret=0;<br />for(int i=0;i<n;i++){<br />trap[i].clear();<br />scanf("%d%d",&v[i],&m);<br />for(int j=0;j<m;j++){<br />scanf("%d",&x);<br />trap[i].push_back(x);<br />}<br />}<br />maxd=n/2;<br />dfs(0,0,0ll);<br />dfs2(maxd,0,0ll);<br />printf("%d/n",ret);<br />}</p><p>return 0;<br />}<br />