exam8.29

咕了好几篇后...

我终于开始重新写了

T1:

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

  于是码出了暴搜...

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

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

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

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

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

考场代码:

#include
#include #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</*for(int q=1;q<=n;q++)  {  for(int w=1;w<=m;w++)  cout< cout< }  cout<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
#include 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< cout< }  cout< for(int w=1;w<=n;w++)  {  for(int e=1;e<=m;e++)  cout< cout< }  cout<cout<<ans<<endl; } } 

 T3:

  不会

  n<=10枚举状态骗分

 考场代码:

#include
#include 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<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; } } 

 

你可能感兴趣的:(exam8.29)