ZJOI2011 Day1 ( bzoj2227~2229 ) 题解
来源:互联网 发布:淘宝购买家具退货 编辑:程序博客网 时间:2024/05/16 16:24
bzoj2227 看电影:bzoj2227(暴力)bzoj2227bzoj2228bzoj2229
先打个暴力,然后找规律。得到答案:ans=(k+1)n-1*(k-n+1)/kn
正解:http://blog.lightning34.cn/?p=166
注意到答案很大,又由于n,k<=200,将k+1,k-n+1,k分解质因数,然后高精乘就可以了
暴力代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 #define ll long long 7 #define N 210 8 ll x,y,g; 9 int i,j,k,n,m,T;10 bool b[N];11 inline ll Gcd(ll x,ll y){12 if(y==0)return x;13 return Gcd(y,x%y);14 }15 inline ll Pow(int x,int y){16 if(y==0)return 1;17 ll Ans=Pow(x,y>>1);18 Ans*=Ans;19 if(y&1)return Ans*x;return Ans;20 }21 inline ll Dfs(int x){22 if(x==n+1)return 1;23 ll Ans=0;24 int j=0;25 for(int i=1;i<=k;i++)26 if(!b[i]){27 b[i]=1;28 Ans+=Dfs(x+1)*(i-j);29 b[j=i]=0;30 }31 return Ans;32 }33 int main()34 {35 for(n=1;n<=9;n++)36 for(k=n;k<=9;k++){37 cout<<n<<" "<<k<<" ";38 memset(b,0,sizeof(b));39 x=Dfs(1);y=Pow(k,n);40 printf("%lld %lld\n",x,y);41 } 42 }43 44 bzoj2227(暴力)
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 #define N 210 7 #define M 510 8 int i,T,j,k,n,m,p[N][N],P[N],Num,ans[N],a2[N],s,a[M],l,x; 9 inline void C(int x){10 if(l==0){11 a[l=1]=x;12 for(l++;a[l];)a[l+1]+=a[l]/10,a[l++]%=10;l--;13 return;14 }15 for(int i=1;i<=l;i++)a[i]*=x;16 for(int i=1;i<=l;i++)a[i+1]+=a[i]/10,a[i]%=10;17 for(l++;a[l];)a[l+1]+=a[l]/10,a[l++]%=10;l--;18 }19 int main()20 {21 for(i=2;i<N;i++){22 s=sqrt((double)i);23 for(j=2;j<=s;j++)24 if(i%j==0)break;25 if(j>s)P[++Num]=i;26 }27 for(i=1;i<N;i++){28 x=i;29 for(j=1;j<=Num;j++)30 while(x%P[j]==0)p[i][P[j]]++,x/=P[j];31 }32 scanf("%d",&T);33 while(T--){34 scanf("%d%d",&n,&k);35 if(n>k){puts("0 1");continue;}36 memset(a,0,sizeof(a));l=0;37 memset(ans,0,sizeof(ans));38 memset(a2,0,sizeof(a2));39 for(i=1;i<=k+1;i++)ans[i]=p[k+1][i]*(n-1);40 if(k-n)for(i=1;i<=k-n+1;i++)ans[i]+=p[k-n+1][i];41 if(k>1)for(i=1;i<=k;i++)42 a2[i]=p[k][i]*n-ans[i],ans[i]-=p[k][i]*n;43 for(i=1;i<N;i++)44 for(i=1;i<N;i++)45 for(j=1;j<=ans[i];j++)C(i); 46 if(!l)putchar('1');47 for(i=l;i;i--)putchar(a[i]+48);putchar(' ');48 memset(a,0,sizeof(a));l=0;49 for(i=1;i<N;i++)50 for(j=1;j<=a2[i];j++)C(i);51 if(!l)putchar('1');52 for(i=l;i;i--)putchar(a[i]+48);putchar('\n');53 }54 return 0;55 }
bzoj2228 礼物:
枚举将哪一面作为底面。枚举每一层,令f[i][j][k]表示在第k层右下角在(i,j)时最大的正方形边长,得到:
f[i][j][k]=min(f[i][j-1][k],f[i-1][j][k],f[i-1][j-1][k])+1
枚举i,j,那么问题就转化为求序列的区间最小值*区间长度的最大值。
枚举每个数,用单调栈求出它作为最小值时向左、右最多延伸的长度即可。
时间复杂度O(n3)
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 #define N 160 6 int i,j,k,n,m,f[N][N][N],p,q,r,b[N],Q[N],t,Ans; 7 bool a[N][N][N],A[N][N][N]; 8 char c[N]; 9 inline int _Max(int x,int y){return x>y?x:y;}10 inline int _Min(int x,int y){return x<y?x:y;}11 inline void Work(){12 for(k=1;k<=r;k++)13 for(i=1;i<=p;i++)14 for(j=1;j<=q;j++)15 if(a[i][j][k])f[i][j][k]=0;else f[i][j][k]=_Min(_Min(f[i-1][j][k],f[i][j-1][k]),f[i-1][j-1][k])+1;16 for(i=1;i<=p;i++)17 for(j=1;j<=q;j++){18 f[i][j][0]=f[i][j][r+1]=-1;19 for(Q[t=1]=0,k=1;k<=r;k++){20 while(f[i][j][Q[t]]>=f[i][j][k])t--;21 b[k]=Q[t]+1;Q[++t]=k;22 }23 for(Q[t=1]=r+1,k=r;k>=1;k--){24 while(f[i][j][Q[t]]>=f[i][j][k])t--;25 Ans=_Max(Ans,f[i][j][k]*(Q[t]-b[k]));Q[++t]=k;26 }27 }28 }29 int main()30 {31 scanf("%d%d%d",&p,&q,&r);32 for(i=1;i<=q;i++)33 for(j=1;j<=p;j++){34 scanf("%s",c+1);35 for(k=1;k<=r;k++)if(c[k]=='P')A[j][i][k]=a[j][i][k]=1;36 }37 for(Work(),i=1;i<=p;i++)38 for(j=1;j<=q;j++)39 for(k=1;k<=r;k++)40 a[i][r-k+1][j]=A[i][j][k];41 for(swap(q,r),Work(),swap(q,r),i=1;i<=p;i++) 42 for(j=1;j<=q;j++)43 for(k=1;k<=r;k++)44 a[k][j][p-i+1]=A[i][j][k];45 swap(p,r);Work();46 printf("%d",Ans<<2);47 return 0;48 }
bzoj2229 最小割:
有一个结论:一个n个点的图最多只有n-1个最小割。
那么我们先求出(s,t)的最小割(X,Y),对于i∈X,j∈Y,更新ans[i][j],再对X,Y中的点分别进行前面的步骤就可以了。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define N 160 6 #define M 3010 7 #define INF 2147483647 8 struct Edge{ 9 int c,t,nx;10 }e[M<<1];11 int Num,i,h[N],Cur[N],j,k,S[N],q[N],l,r,n,m,a[N],A[N],Ans[N][N],x,y,z,_Ans,T,Q;12 bool b[N],B[N];13 inline int _Min(int x,int y){return x<y?x:y;}14 inline void Add(int x,int y,int z){e[++Num].t=y;e[Num].c=z;e[Num].nx=h[x];h[x]=Num;}15 inline bool Bfs(int s,int t){16 memset(b,0,sizeof(b));17 b[s]=1;l=0;q[r=1]=s;S[s]=0;18 while(++l<=r){19 for(int i=h[q[l]];i;i=e[i].nx)20 if(e[i].c&&!b[e[i].t])q[++r]=e[i].t,S[e[i].t]=S[q[l]]+1,b[e[i].t]=1;21 }22 return b[t];23 }24 inline int Dfs(int x,int a,int t){25 if(a==0||x==t)return a;26 int f,F=0;27 for(int& i=Cur[x];i;i=e[i].nx)28 if(S[e[i].t]==S[x]+1&&e[i].c&&(f=Dfs(e[i].t,_Min(a-F,e[i].c),t))){29 e[i].c-=f;e[i^1].c+=f;F+=f;30 if(a==F)break;31 }32 return F;33 }34 inline int Max_flow(int s,int t){35 int Ans=0;36 while(Bfs(s,t)){37 for(int i=1;i<=n;i++)Cur[i]=h[i];38 Ans+=Dfs(s,INF,t);39 }40 return Ans;41 }42 inline void Dfs(int x){43 B[x]=1;44 for(int i=h[x];i;i=e[i].nx)45 if(e[i].c&&!B[e[i].t])Dfs(e[i].t);46 }47 inline void Divide(int l,int r){48 if(l==r)return;49 for(int i=2;i<=Num;i+=2)e[i].c=e[i+1].c=(e[i].c+e[i+1].c)>>1;50 int Mf=Max_flow(a[l],a[r]);51 memset(B,0,sizeof(B));52 Dfs(a[l]);53 for(int i=1;i<=n;i++)54 if(B[i])for(int j=1;j<=n;j++)55 if(!B[j])Ans[i][j]=Ans[j][i]=_Min(Ans[i][j],Mf);56 int l1=l,l2=r;57 for(int i=l;i<=r;i++)58 if(B[a[i]])A[l1++]=a[i];else A[l2--]=a[i];59 for(int i=1;i<=n;i++)a[i]=A[i];60 Divide(l,l1-1);Divide(l2+1,r);61 }62 int main()63 {64 scanf("%d",&T);65 while(T--){66 scanf("%d%d",&n,&m);67 for(Num=1,memset(h,0,sizeof(h)),i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&z),Add(x,y,z),Add(y,x,z);68 for(i=1;i<=n;i++)a[i]=i;69 memset(Ans,127,sizeof(Ans));70 Divide(1,n);71 scanf("%d",&Q);72 while(Q--){73 scanf("%d",&x);74 for(_Ans=0,i=1;i<=n;i++)75 for(j=i+1;j<=n;j++)76 if(Ans[i][j]<=x)_Ans++;77 printf("%d\n",_Ans);78 }79 putchar('\n');80 }81 }
概率就是可行方案除以所有方案。
所有方案就是 kn。
考虑可行方案,如果加上一个座位使得所有的位置连成环的话,方案数就是 (k+1)n,另外由于是环,有重复的情况,所以要除以 k+1。
然后再断开,只要是空位的都可以断开,所以断开的方案数为 k−n+1。
所以最后的可行方案数为 (k−n+1)(k+1)n−1。
答案可以质因数分解之后高精度求。
阅读全文
0 0
- ZJOI2011 Day1 ( bzoj2227~2229 ) 题解
- bzoj2227: [Zjoi2011]看电影(movie)
- BZOJ2227: [Zjoi2011]看电影(movie)
- [比赛][ZJOI2011 day1]
- [BZOJ2227][Zjoi2011][找规律][排列组合][数学]看电影(movie)
- 2229: [Zjoi2011]最小割
- noip2011题解day1
- 09-Day1 题解
- JZWC【Day1】题解&总结
- GDOI2016 day1题解
- NOIP2015 Day1题解
- Noip 2013 day1 题解
- [NOIP2015]day1题解集合
- 集训题解-Day1
- [题解]NOIP2017 Day1 Solution
- NOIP 2017 Day1 题解?
- bzoj 2229: [Zjoi2011]最小割
- BZOJ 2229:[Zjoi2011]最小割
- flex布局(3)
- 51Nod 1228 -- 伯努利数
- bzoj4771 -- dfs序+倍增+主席树
- error MSB600: “cmd.exe”已退出 代码为3
- UnityAI行为------群组行为
- ZJOI2011 Day1 ( bzoj2227~2229 ) 题解
- bzoj2324 [ ZJOI2011 ] -- 费用流
- bzoj2187 -- 类欧几里得算法
- bzoj2712 -- 类欧几里得算法
- 集锦
- bzoj1856 [ SCOI2010 ] -- 卡特兰数
- 10、jQuery插件之artDialog弹窗插件
- bzoj3175 [ TJOI2013 ] -- 二分图最大点独立集
- springAOP advice方法执行两次 解决方法