Free Candies UVA - 10118

原题链接

考察:记忆化搜索

思路:

       dfs模拟即可,用map判断当前数字出现过几次.但是回溯的时候要注意,如果本该有的数字没有说明被凑成了一对,但是恢复要恢复成1,如果有就要去掉这个数字.

本蒟蒻真的写得很繁琐,这位大佬利用位运算0 1的性质避免了判断2,很妙 GO

        网上题解基本都用了步数作为参数,本蒟蒻是完全没想到.

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <vector>
 6 #include <map>
 7 using namespace std;
 8 const int N = 42;
 9 bool st[N][N][N][N];
10 vector<int> v[5];
11 map<int,int> mp;
12 int n,ans,cnt;
13 void dfs(int i,int j,int k,int w)
14 {
15     if(i>=n&&j>=n&&k>=n&&w>=n) return;
16     if(st[i][j][k][w]) return;
17     st[i][j][k][w] = 1;
18     if(i<n) 
19     {
20         if(mp.size()>=5) return;
21         mp[v[1][i]]++;
22         if(mp[v[1][i]]>=2)
23           cnt++,mp.erase(v[1][i]);
24         ans = max(cnt,ans);
25         dfs(i+1,j,k,w);
26         if(!mp.count(v[1][i])) cnt--,mp[v[1][i]] = 1;
27         else mp.erase(v[1][i]);
28     }
29     if(j<n)
30     {
31         if(mp.size()>=5) return;
32         mp[v[2][j]]++;
33         if(mp[v[2][j]]>=2)
34           cnt++,mp.erase(v[2][j]);
35         ans = max(cnt,ans);
36         dfs(i,j+1,k,w);
37         if(!mp.count(v[2][j])) cnt--,mp[v[2][j]] = 1;
38         else mp.erase(v[2][j]);
39     }
40     if(k<n)
41     {
42         if(mp.size()>=5) return;
43         mp[v[3][k]]++;
44         if(mp[v[3][k]]>=2) 
45            cnt++,mp.erase(v[3][k]);
46         ans = max(cnt,ans);
47         dfs(i,j,k+1,w);
48         if(!mp.count(v[3][k])) cnt--,mp[v[3][k]] = 1;
49         else mp.erase(v[3][k]);
50     }
51     if(w<n)
52     {
53         if(mp.size()>=5) return;
54         mp[v[4][w]]++;
55         int t = v[4][w];
56         if(mp[v[4][w]]>=2)
57           cnt++,mp.erase(v[4][w]);
58         ans = max(cnt,ans);
59         dfs(i,j,k,w+1);
60         if(!mp.count(v[4][w])) cnt--,mp[v[4][w]] = 1;
61         else mp.erase(v[4][w]);
62     }
63 }
64 int main()
65 {
66     while(scanf("%d",&n)!=EOF&&n)
67     {
68         memset(st,0,sizeof st);
69         mp.clear(); ans =0; cnt = 0;
70         for(int i=1;i<=4;i++) v[i].clear();
71         for(int i=1;i<=n;i++)
72           for(int j=1;j<=4;j++)
73           {
74               int x; scanf("%d",&x);
75               v[j].push_back(x);
76           }
77         dfs(0,0,0,0);
78         printf("%d\n",ans);
79     }
80     return 0;
81 }

 

上一篇:LeetCode算法题:拥有糖果最多的孩子


下一篇:[LeetCode] 1103. Distribute Candies to People