bzoj1306的强化版(双倍经验)
搜索,假设你现在刚匹配完第
i
个,那么
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
void read(int &x)
{
char c;
while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0';
}
const int maxn = 12;
const ll Mod = 1e9+7;
map<ll, ll>H[maxn];
int n,a[maxn];
int qu[maxn],tail;
bool cmp(int x,int y){return x>y;}
ll dfs(int x);
ll cal(int x,int y)
{
if(y>n)
{
if(!a[x]) return dfs(x+1);
else return 0ll;
}
if((n-y+1)*3<a[x]) return 0ll;
ll re=0;
if(a[x]>=3)
{
a[x]-=3;
(re+=cal(x,y+1))%=Mod;
a[x]+=3;
}
if(a[x]&&a[y])
{
a[x]--; a[y]--;
(re+=cal(x,y+1))%=Mod;
a[x]++; a[y]++;
}
if(a[y]>=3)
{
a[y]-=3;
(re+=cal(x,y+1))%=Mod;
a[y]+=3;
}
return re;
}
ll dfs(int x)
{
if(x>n) return 1ll;
tail=0;
for(int i=x;i<=n;i++) qu[++tail]=a[i];
sort(qu+1,qu+tail+1,cmp);
ll tmp=0;
for(int i=1;i<=tail;i++) (tmp*=(ll)28)+=(ll)qu[i];
if(H[x].count(tmp)>0) return H[x][tmp];
else
{
ll re=cal(x,x+1);
H[x][tmp]=re;
return re;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1,cmp);
printf("%lld\n",dfs(1));
return 0;
}