题目大意:有4堆糖果, 每堆糖果有n颗糖果,然后给出每颗糖果的类型1~20,然后只有取走当前堆的前面一颗糖果后才可以取后面的糖果, 然后小伙伴有一个篮子,篮子可以装5个糖果,如果篮子中的糖果存在相同类型的两个糖果,便可以将这两颗糖果算成一对放进腰包,问,小伙伴按什么样的方式取糖果可以取到最多的糖果。
解题思路:记忆化搜索,开一个四维数组记录当前4堆糖果取走相应个数后能拿到的最多对糖果数。
// Created by Chenhongwei in 2015.
// Copyright (c) 2015 Chenhongwei. All rights reserved.
#include"iostream"
#include"cstdio"
#include"cstdlib"
#include"cstring"
#include"climits"
#include"queue"
#include"cmath"
#include"map"
#include"set"
#include"stack"
#include"vector"
#include"sstream"
#include"algorithm"
using namespace std;
typedef long long ll;
int g[50][5], dp[50][50][50][50], vis[25], b[10];
int n;
int dfs(int cnt)
{
int &cur = dp[b[0]][b[1]][b[2]][b[3]];
if (cnt == 5)
return cur = 0;
if (cur != -1)
return cur;
cur = 0;
for (int i = 0; i < 4; i++)
{
if (b[i] == n)
continue;
int tmp = g[b[i]++][i];
if (vis[tmp])
{
vis[tmp] = 0;
cur = max(cur, dfs(cnt - 1) + 1);
vis[tmp] = 1;
}
else
{
vis[tmp] = 1;
cur = max(cur, dfs(cnt + 1));
vis[tmp] = 0;
b[i]--;
}
return cur;
}
int main()
{
//ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while (cin >> n && n)
{
memset(dp, -1, sizeof dp);
memset(vis, 0, sizeof vis);
memset(b, 0, sizeof b);
for (int i = 0; i < n; i++)
for (int j = 0; j < 4; j++)
cin >> g[i][j];
cout << dfs(0) << endl;
}
return 0;
}