题意:链接略
方法:记忆化搜索
解析:
记忆化搜索,状态内部压缩起始点以及所有点目前剩下的未匹配的分值。
注意不可以用map,因为我们记忆化的目的其实是大部分消除冗余的等于0的方案。
所以就得上hash表….
用map坑死我了。
代码:
#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 15
#define szy 30123
#define mod 1000000007
using namespace std;
typedef long long ll;
int a[N];
int n;
ll ans;
int head[80010],cnt;
struct node
{
ll from,to,val;
int next;
}edge[80010];
void init()
{
memset(head,-1,sizeof(head));
cnt=1;
}
void edgeadd(ll from,ll to,ll val)
{
edge[cnt].from=from,edge[cnt].to=to,edge[cnt].val=val;
edge[cnt].next=head[from];
head[from]=cnt++;
}
ll find(ll x)
{
int szyszy=x%szy;
for(int i=head[szyszy];i!=-1;i=edge[i].next)
{
if(edge[i].to==x)return edge[i].val;
}
return -1;
}
ll ins(ll x,ll val)
{
int szyszy=x%szy;
edgeadd(szyszy,x,val);
}
ll get_hash(int tmp[])
{
ll ret=0;
for(int i=0;i<=n;i++)ret=ret*30+tmp[i];
return ret;
}
void bac(int tmp[],ll x)
{
for(int i=n;i>=0;i--)tmp[i]=x%30,x/=30;
}
ll dfs0(ll x);
ll dfs(int arr[],int nowx,int nowy)
{
ll ans=0;
if(nowy>n)
{
if(arr[nowx]==0)
{
int t[N];
for(int i=1;i<=n;i++)t[i]=arr[i];
sort(t+1,t+n+1);t[0]=nowx;
return dfs0(get_hash(t));
}else return 0;
}
arr[nowx]-=3;
if(arr[nowx]>=0&&arr[nowy]>=0)ans+=dfs(arr,nowx,nowy+1);
arr[nowx]+=3;
arr[nowy]-=3;
if(arr[nowx]>=0&&arr[nowy]>=0)ans+=dfs(arr,nowx,nowy+1);
arr[nowy]+=3;
arr[nowx]--,arr[nowy]--;
if(arr[nowx]>=0&&arr[nowy]>=0)ans+=dfs(arr,nowx,nowy+1);
arr[nowx]++,arr[nowy]++;
return ans;
}
ll dfs0(ll x)
{
int tmp=find(x);
if(tmp!=-1)return tmp;
int c[N];
bac(c,x);
if(c[0]==n&&c[n]==0)return 1;
ll sum=dfs(c,c[0]+1,c[0]+2);
ins(x,sum);
return sum;
}
int main()
{
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+n+1);
printf("%lld\n",dfs0(get_hash(a))%mod);
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-06 09:50:42