这道题比较难,状压dp,再加两个预处理
#include<bits/stdc++.h>
using namespace std;
const int maxn = (1 << 20) + 10;
int a[22],n;
bool dp[maxn];
vector<int> g[maxn];
int len[maxn];
int p[maxn], sz;
int t[maxn];
int lowbit(int x) {
return x & (-x);
}
void init()
{
for(int i = 0 ; i < sz ; i ++)
{
int temp = p[i];
int x[3], cnt = 0;
while(temp) {
int h = lowbit(temp);
x[cnt ++] = t[h];
temp -= h;
}
x[0] = a[n - x[0] - 1];
x[1] = a[n - x[1] - 1];
x[2] = a[n - x[2] - 1];
sort(x, x + 3);
if(x[0] > x[2] - x[1])
dp[p[i]] = 1;
}
}
void f() {
for(int i = 0 ; i < 20; i ++) {
t[1 << i] = i;
}
for(int i = 1; i < maxn; i ++)
{
len[i] = len[i - lowbit(i)] + 1;
if(len[i] == 3)
{
p[sz ++] = i;
}
}
int sum = 0;
for(int i = 0; i < (1 << 20); i ++)
{
if(len[i] % 3 != 0)
continue;
for(int j = 0; j < sz; j ++)
{
if((i & p[j]) != 0)
continue;
g[i].push_back(p[j]);
}
sum = sum + g[i].size();
}
// cout << sum << endl;
}
int main()
{
f();
// cout << "ok" << endl;
// cout << p[0] << endl;
int T;
scanf("%d",&T);
for(int u = 1; u <= T; u ++)
{
memset(dp, 0, sizeof(dp));
int ma = 0;
scanf("%d",&n);
for(int i = 0; i < n ; i ++)
scanf("%d",&a[i]);
init();
dp[0] = 1;
for(int S = 0; S < (1 << n); S ++)
{
if(dp[S] == 0)
continue;
for(int j = 0; j < g[S].size(); j ++)
{
if(dp[g[S][j]] && S + g[S][j] < (1 << n))
dp[S + g[S][j]] = 1;
}
}
for(int i = 0 ; i < (1 << n); i ++)
{
if(dp[i] == 1)
{
ma = max(ma, len[i] / 3);
}
}
printf("Case #%d: ",u);
printf("%d\n",ma);
}
return 0;
}