• 4250. 【五校联考7day1附加题】路径


    Description&Data Constraint

    A国有 (n) 个城市,编号为 1 到 (n),任意两个城市之间有一条路。shlw闲得没事干想周游A国,及从城市 1 出发,经过且仅经过除城市 1 外的每个城市 1 次(城市 1 两次),最后回到城市 1。由于shlw很傻,他只愿意走一定长度,多了少了都不干,现在他想知道一共有多少种方案可供选择。

    (1le nle14,1le A_{i,j}le10^8,1le lle 2 imes 10^9)

    Solution

    考虑折半搜索。

    哈希记录 ((k,s,sum)) 表示在搜完一半之后,当前点为 (k),点的到达情况为 (s),长度为 (sum)

    再次搜索,对于每个搜索判断对应的状态的方案数。

    若第二次搜索完的状态为 ((k',s',sum')),则对应的状态是 ((k',2^n-1-s'-1+2^{k-1},l-sum'))

    其中 (2^n-1-s'-1+2^{k-1}) 的意思是总状态-当前状态-1+当前点。

    Code

    #pragma GCC optimize(2)
    #include<cstdio>
    #define mod 9999997
    #define ll long long
    using namespace std;
    struct hs
    {
    	int k,s,sum;
    	ll tot;
    }hash[20000010];
    int n,l,dis[20][20];
    ll ans,er[20];
    bool b[20];
    void inhash(ll k,ll s,ll sum)
    {
    	ll x=k*s%mod*sum%mod;
    	while (hash[x].k)
    	{
    		if (hash[x].k==k&&hash[x].s==s&&hash[x].sum==sum)
    		{
    			++hash[x].tot;
    			return;
    		}
    		++x;
    		if (x>20000000) x=0;
    	}
    	hash[x].k=k;hash[x].s=s;hash[x].sum=sum;hash[x].tot=1;
    }
    void find(ll k,ll s,ll sum)
    {
    	ll x=k*s%mod*sum%mod;
    	while (hash[x].k)
    	{
    		if (hash[x].k==k&&hash[x].s==s&&hash[x].sum==sum)
    		{
    			ans+=hash[x].tot;
    			return;
    		}
    		++x;
    		if (x>20000000) x=0;
    	}
    }
    void dfs1(int now,int x,int s,int sum,int num)
    {
    	if (x>num)
    	{
    		inhash(now,s,sum);
    		return;
    	}
    	for (int i=2;i<=n;++i)
    		if (!b[i])
    		{
    			b[i]=true;
    			if (sum+dis[now][i]<=l) dfs1(i,x+1,s+er[i-1],sum+dis[now][i],num);
    			b[i]=false;
    		}
    }
    void dfs2(int now,int x,int s,int sum,int num)
    {
    	if (x>num)
    	{
    		find(now,er[n]-1-s-1+er[now-1],l-sum);
    		return;
    	}
    	for (int i=2;i<=n;++i)
    		if (!b[i])
    		{
    			b[i]=true;
    			if (sum+dis[now][i]<=l) dfs2(i,x+1,s+er[i-1],sum+dis[now][i],num);
    			b[i]=false;
    		}
    }
    int main()
    {
    	freopen("way.in","r",stdin);
    	freopen("way.out","w",stdout);
    	er[0]=1;
    	for (int i=1;i<=15;++i)
    		er[i]=er[i-1]<<1;
    	scanf("%d%d",&n,&l);
    	for (int i=1;i<=n;++i)
    		for (int j=1;j<=n;++j)
    			scanf("%d",&dis[i][j]);
    	dfs1(1,1,0,0,n>>1);
    	dfs2(1,1,0,0,n-(n>>1));
    	printf("%lld
    ",ans);
    	return 0;
    } 
    
  • 相关阅读:
    1.1 What is the plug-in?
    Chapter 8 The Simplest Plug-in Solution
    Chapter 7 Resources in Plug-In(1)
    Chapter 1: Plug-in programing from past to the future
    Android插件化的兼容性(下):突破Android P中灰黑名单的限制
    Android插件化的兼容性(中):Android P的适配
    Android插件化的兼容性(上):Android O的适配
    pandas 学习 第12篇:DataFrame 避免链式赋值
    NumPy 学习 第三篇:矢量化和广播
    Wait Type 整理
  • 原文地址:https://www.cnblogs.com/Livingston/p/15120829.html
Copyright © 2020-2023  润新知