首页 > 代码库 > UVA10118Free Candies

UVA10118Free Candies

一开始看数据范围不大想直接暴力搜索,仔细考虑搜索的状态会有很多重复,搜索量仍然很大。

这就是传说中的记忆化搜索。。。number数组表示每一列取了多少个数,ans每一列取得相应数字个数时的最优解。

第九章前面的代码用了引用,在记忆化搜索里面很方便。这个题还要注意搜索的时候要回溯,搜不下去了要尝试另一种。

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <bits/stdc++.h>
 4 #include <cstdio>
 5 
 6 using namespace std;
 7 
 8 typedef long long ll;
 9 const int maxn = 40 + 10;
10 int G[maxn][4];
11 int ans[maxn][maxn][maxn][maxn];
12 bool book[maxn*maxn];
13 int number[4];
14 int n;
15 
16 int dfs(int cnt,int a,int b,int c,int d)
17 {
18     number[0] = a, number[1] = b, number[2] = c, number[3] = d;
19     int & num = ans[a][b][c][d];
20     if(num != 0 || cnt >= 5)return num;
21     int sum = 0;
22     for(int i = 0 ; i < 4 ; i ++)
23     {
24         if(number[i] >= n)continue;
25         int v = G[number[i]][i];
26         number[i]++;
27         if(!book[v])
28         {
29             book[v] = true;
30             sum = max(sum,dfs(cnt-1,number[0],number[1],number[2],number[3])+1);
31             book[v] =false;
32             number[i] --;
33         }
34         else
35         {
36             book[v] = false;
37             sum = max(sum,dfs(cnt+1,number[0],number[1],number[2],number[3]));
38             book[v] = true;
39             number[i]--;
40         }
41     }
42     num += sum;
43     return num;
44 }
45 int main(int argc, char const *argv[])
46 {
47     while (cin >> n && n)
48     {
49         memset(ans, 0, sizeof(ans));
50         memset(book,true,sizeof(book));
51         for (int i = 0 ; i < n ; i++)
52             for (int j = 0 ; j < 4 ; j++)
53                 cin >> G[i][j];
54         cout << dfs(0,0,0,0,0) << endl;
55     }
56     return 0;
57 }

 

UVA10118Free Candies