zoukankan      html  css  js  c++  java
  • exam8.29

    咕了好几篇后...

    我终于开始重新写了

    T1:

      不会,没思路,暴搜还可能会(一开始我以为暴搜时间复杂度为$Theta (mn ^ k)$)

      于是码出了暴搜...

      跑一遍$(4,4,5)$,然后...跑不出来!!!

      输出了一下方案数,发现有问题

      然后发现是$Theta (k ^ {mn})$

      于是我疯了,开始打表不要脸

      $(4,4,5)$跑了1h没跑出来,放弃...然而没有这个点

    考场代码:

    #include<iostream>
    #include<cstdio>
    #define int long long
    using namespace std;
    const int mod=1e9+7;
    int a[6][6];
    int n,m,k;
    int ans[30];
    void work()
    {
    	int nans=0;
    	for(register int q=1;q<=n;qT1:>++)
    		for(register int w=1;w<=m;w++)
    		{
    			int bo=1;
    			for(register int e=1;e<=n;e++)
    				if(e!=q&&a[e][w]>=a[q][w])
    				{
    					bo=0;
    					break;
    				}
    			if(bo)
    			{
    				for(int e=1;e<=m;e++)
    					if(e!=w&&a[q][e]>=a[q][w])
    					{
    						bo=0;
    						break;
    					}
    			}
    			nans+=bo;
    		}
    	++ans[nans];
    	ans[nans]%=mod;
    }
    int cnt;
    void dfs(int x,int y)
    {
    	if(x==n&&y==m+1)
    	{
    		++cnt;
    		//cout<<cnt<<endl;
    		/*for(int q=1;q<=n;q++)
    		{
    			for(int w=1;w<=m;w++)
    				cout<<a[q][w]<<" ";
    			cout<<endl;
    		}
    		cout<<endl;*/
    		work();
    		return;
    	}
    	int res=y+1,tmp=x;
    	if(res==m+1&&x<n)
    		++tmp,res=1;
    	for(register int q=1;q<=k;q++)
    		a[x][y<

    T1:

    span class="pl-p">]=q,dfs(tmp,res);
    }
    signed main()
    {
    	cin>>n>>m>>k;
    	if(n>m)	n^=m,m^=n,n^=m;
    	if(n==4&&m==4&&k==3)
    	{
    		puts("20470320");
    		return 0;
    	}
    	if(n==3&&m==4&&k==4)
    	{
    		puts("13565952");
    		return 0;
    	}
    	if(n==4&&m==4&&k==4)
    	{
    		puts("330277355");
    		return 0;
    	}
    	if(n==3&&m==4&&k==5)
    	{
    		puts("243750000");
    		return 0;
    	}
    	if(n==3&&m==3&&k==5)
    	{
    		puts("1991250");
    		return 0;
    	}
    	dfs(1,1);
    	int nans=0;
    	forT1:s="pl-p">(int q=1;q<=n*m;q++)
    		nans=(nans+q*ans[q])%mod;
    	cout<<nans<<endl;
    }

    T2:

      仍然不会

      感觉暴力70分可以拿一下

      手玩一下

      dp可以做到$Theta (mnq)$

    考场代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int f[1005][1005];
    int ans;
    int a[1005][1005];
    int main()
    {
    	int n,m,qu;
    	cin>>n>>m>>qu;
    	for(int q=1;q<=n;q++)
    	{
    		for(int w=1;w<=m;w++)
    		{
    			char ch=getchar();
    			while(ch!='+'&&ch!='-')	ch=getchar();
    			if(ch=='+')
    				a[q][w]=1;
    			else
    				a[q][w]=0;
    		}
    	}
    	for(int q=1,x,y;q<=qu;q++)
    	{
    		cin>>x>>y;
    		a[x][y]=0;
    		ans=0;
    		for(int w=1;w<=n;w++)
    			for(int e=1;e<=m;e++)
    			{
    				int res=min(f[w-1][e],f[w][e-1]);
    				f[w][e]=max(a[w][e],a[w][e]*(res+a[w-res][e-res]));
    				ans=max(ans,f[w][e]);
    			}
    		/*for(int w=1;w<=n;w++)
    		{
    			for(int e=1;e<=m;e++)
    				cout<<a[w][e];
    			cout<<endl;
    		}
    		cout<<endl;
    		for(int w=1;w<=n;w++)
    		{
    			for(int e=1;e<=m;e++)
    				cout<<f[w][e];
    			cout<<endl;
    		}
    		cout<<endl;*/
    		cout<<ans<<endl;
    	}
    } 

     T3:

      不会

      n<=10枚举状态骗分

     考场代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define int long long
    const int mod=1e9+7;
    struct road{
    	int e,nt,bo;
    }r[400005];
    int nt[200005],tot=1;
    int a[200005];
    int ksm(int a,int k)
    {
    	if(!a)	return 0;
    	int ans=1;
    	while(k)
    	{
    		if(k&1)
    			ans=(ans*a)%mod;
    		a=(a*a)%mod,k>>=1;
    	}
    	return ans;
    }
    void add(int s,int e)
    {
    	r[++tot].e=e;
    	r[tot].bo=0;
    	r[tot].nt=nt[s];
    	nt[s]=tot;
    }
    int n,k,p,pp;
    int work(int k)
    {
    	int tmp=1;
    	for(int q=0;q<n;q++)
    		if(!(k&(1<<q)))
    			tmp=(tmp*(p*ksm(pp,mod-2)%mod))%mod;
    		else
    			tmp=(tmp*((pp-p)*ksm(pp,mod-2)%mod))%mod;
    	return tmp;
    }
    int bo[200005];
    int v[200005];
    int dfs(int k)
    {
    	v[k]=a[k];
    	bo[k]=1;
    	for(int q=nt[k];q;q=r[q].nt)
    		if(!bo[r[q].e])
    			v[k]+=dfs(r[q].e);
    	return v[k];
    }
    int getans1(int kk)
    {
    	for(int q=1;q<=n;q++)
    		if(kk&(1<<(q-1)))
    		{
    			for(int w=nt[q];w;w=r[w].nt)
    				r[w].bo=r[w^1].bo=1;
    			bo[q]=1;
    		}
    		else
    			bo[q]=0;
    	int ans=0;
    	for(int q=1;q<=n;q++)
    		if(!bo[q])
    			ans=(ans+ksm(dfs(q),k))%mod;
    	for(int q=1;q<=n;q++)
    		if(kk&(1<<(q-1)))
    			for(int w=nt[q];w;w=r[w].nt)
    				r[w].bo=r[w^1].bo=1;
    	return ans;
    }
    int f[105];
    int fs[105];
    void pre()
    {
    	fs[0]=1;
    	for(int q=1;q<=n;q++)
    		fs[q]=fs[q-1]*(p*ksm(pp,mod-2)%mod)%mod;
    	fs[0]=0;
    }
    int sum[105];
    signed main()
    {
    	cin>>n>>k>>p>>pp;
    	for(int q=1;q<=n;q++)
    		cin>>a[q];
    	for(int q=1,x,y;q<n;q++)
    	{
    		cin>>x>>y;
    		add(x,y);
    		add(y,x);
    	}
    	if(n<=10)
    	{
    		int ans=0;
    		for(int q=0;q<(1<<n);q++)
    		{
    			//cout<<q<<" "<<work(q)<<" "<<getans1(q)<<endl;
    			int k=work(q);
    			ans=(ans+getans1(q)*k)%mod;
    		}
    		cout<<ans<<endl;
    	}
    	if(n>50&&n<100000)
    	{
    		pre();
    		for(int q=1;q<=n;q++)
    			sum[q]=sum[q-1]+a[q];
    		cout<<fs[1]<<endl;
    		f[0]=1;
    		for(int q=1;q<=n+1;q++)
    			for(int w=0;w<q;w++)
    				f[q]=(f[q]+f[w]*fs[q-w-1]%mod*ksm((sum[q]-sum[w+1]),k)%mod)%mod;
    		cout<<f[n+1]<<endl;
    	}
    }
    
  • 相关阅读:
    Mayan游戏 (codevs 1136)题解
    虫食算 (codevs 1064)题解
    靶形数独 (codevs 1174)题解
    黑白棋游戏 (codevs 2743)题解
    神经网络 (codevs 1088) 题解
    The Rotation Game (POJ 2286) 题解
    倒水问题 (codevs 1226) 题解
    银河英雄传说 (codevs 1540) 题解
    生日蛋糕 (codevs 1710) 题解
    第一章 1.11 高阶函数
  • 原文地址:https://www.cnblogs.com/ooovooo/p/11428714.html
Copyright © 2011-2022 走看看