【bzoj4806~bzoj4809】 象棋四连发 DP-高精度-匈牙利算法-dfs

都是经典题了吧。。我好无聊。。

4806

4806-1801是双倍经验。。DP方程看代码吧。。

 1 /* http://www.cnblogs.com/karl07/ */
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8
 9 #define ll long long
10 //#define P 9999973 //bzoj1801
11 #define P 999983 //bzoj4806
12 #define C(x) ((x)*(x-1)/2)
13 int n,m;
14 ll f[105][105][105];
15
16 int main(){
17     scanf("%d%d",&n,&m);
18     f[0][0][0]=1;
19     for (int i=1;i<=n;i++){
20         for (int j=0;j<=m;j++){
21             for (int k=0;k<=m-j;k++){
22                 f[i][j][k]+=f[i-1][j][k];
23                 if (j>=1)          f[i][j][k]+=f[i-1][j-1][k]*(m-j-k+1);
24                 if (k>=1 && j<=m-1)f[i][j][k]+=f[i-1][j+1][k-1]*(j+1);
25                 if (j>=2)          f[i][j][k]+=f[i-1][j-2][k]*C(m-j-k+2);
26                 if (k>=2 && j<=m-2)f[i][j][k]+=f[i-1][j+2][k-2]*C(j+2);
27                 if (j>=1 && k>=1)  f[i][j][k]+=f[i-1][j][k-1]*j*(m-j-k+1);
28                 f[i][j][k]%=P;
29             }
30         }
31     }
32     ll ans=0;
33     for (int i=0;i<=m;i++){
34         for (int j=0;j<=m-i;j++){
35             ans+=f[n][i][j];
36             ans%=P;
37         }
38     }
39     printf("%lld\n",ans);
40     return 0;
41 }

4807

就是 max(m,n) C min (m,n)

 1 /* http://www.cnblogs.com/karl07/ */
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8 struct INT {
 9     int b,a[60];
10     INT (){b=0; for (int i=0;i<=50;i++) a[i]=0;}
11 };
12 int A,B,c,n,m;
13 int P[1000005],p[1000005],cnt[1000005],ip[1000005];
14 INT Int(int x){
15     INT a;
16     for (a.b=0 ; x ; a.a[++a.b]=x%10,x/=10);
17     return a;
18 }
19
20 INT operator * (const INT &x,const INT &y){
21     INT a;
22     a.b=min(50,x.b+y.b-1);
23     for (int i=1;i<=x.b;i++) for (int j=1;j<=y.b;j++) if (i+j-1<=50) a.a[i+j-1]+=x.a[i]*y.a[j];
24     for (int i=1;i<=a.b;a.b+=(i==a.b && a.a[i+1] && i+1<=50),i++)  a.a[i+1]+=a.a[i]/10,a.a[i]%=10;
25     for (;a.a[a.b]==0 && a.b!=1; a.b--);
26     return a;
27 }
28
29 void print_INT(INT x){
30     for (int i=min(x.b,50);i>=1;i--) printf("%d",x.a[i]);
31     puts("");
32 }
33
34 void Prime(int n){
35     for (int i=2;i<=n;i++){
36         if (!P[i]){
37             p[++c]=i,ip[i]=c;
38             for (int j=i+i;j<=n;j+=i) P[j]=1;
39         }
40     }
41 }
42
43 void pt(int x) {
44     printf("%d\n",x);
45 }
46
47 void fac(int x,int y){
48     for (int i=1;i<=c && P[x];i++) while (!(x%p[i])) x/=p[i],cnt[i]+=y;
49     cnt[ip[x]]+=y;
50 }
51
52 INT ans=Int(1);
53 int main(){
54     scanf("%d%d",&A,&B);
55     n=max(A,B),m=max(max(A,B)-min(A,B),min(A,B));
56     Prime(n);
57     for (int i=m+1;i<=n;i++) fac(i,1);
58     for (int i=2;i<=n-m;i++) fac(i,-1);
59     for (int i=1;i<=c;i++) while (cnt[i]--) ans=ans*Int(p[i]);
60     print_INT(ans);
61     return 0;
62 }

4808

黑白染色然后匈牙利

 1 /* http://www.cnblogs.com/karl07/ */
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8
 9 struct edge{
10     int next,to;
11 }e[1000005];
12 int ade,n,m,cnt,T,c;
13 int x[]={1,2,-1,-2,-1,2,1,-2};
14 int y[]={2,1,-2,-1,2,-1,-2,1};
15 int mp[205][205],id[205][205],first[1000005],vis[1000005],match[1000005];
16
17 void addedge(int x,int y){
18     e[++ade].next=first[x];
19     e[ade].to=y;
20     first[x]=ade;
21 }
22
23 bool check(int x,int y){
24     return (x>=1 && x<=n && y>=1 && y<=m && !mp[x][y]);
25 }
26
27 #define s e[x].to
28 bool hungary(int p){
29     for (int x=first[p];x;x=e[x].next){
30         if (vis[s]!=T){
31             vis[s]=T;
32             if (!match[s] || hungary(match[s])) {match[s]=p; return 1;}
33         }
34     }
35     return 0;
36 }
37 #undef s
38
39 int main(){
40     scanf("%d%d",&n,&m);
41     for (int i=1;i<=n;i++){
42         for (int j=1;j<=m;j++){
43             scanf("%d",&mp[i][j]);
44             cnt+=(!mp[i][j]);
45             id[i][j]=++c;
46         }
47     }
48     for (int i=1;i<=n;i++)
49         for (int j=1;j<=m;j++)
50             if (((i+j)&1) && !mp[i][j])for (int k=0;k<8;k++) if (check(i+x[k],j+y[k])) addedge(id[i][j],id[i+x[k]][j+y[k]]);
51     for (int i=1;i<=n;i++){
52         for (int j=1;j<=m;j++){
53             if (!mp[i][j] && ((i+j)&1)){
54                 T=id[i][j];
55                 cnt-=hungary(T);
56             }
57         }
58     }
59     printf("%d\n",cnt);
60     return 0;
61 }

4809

直接dfs

 1 /* http://www.cnblogs.com/karl07/ */
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8
 9 int n,ans;
10 int ban[20][20],y[20],a[40],b[40];
11
12 void dfs(int i){
13     if (i>n) {ans++; return;}
14     for(int j=1;j<=n;j++) if (!(ban[i][j] || y[j] || a[i+j-1] || b[n-i+j] )){
15         y[j]=a[i+j-1]=b[n-i+j]=1;
16         dfs(i+1);
17         y[j]=a[i+j-1]=b[n-i+j]=0;
18     }
19 }
20
21 int main(){
22     scanf("%d",&n);
23     for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) scanf("%d",&ban[i][j]);
24     dfs(1);
25     printf("%d\n",ans);
26     return 0;
27 }

皇后

时间: 2024-08-01 16:37:27

【bzoj4806~bzoj4809】 象棋四连发 DP-高精度-匈牙利算法-dfs的相关文章

匈牙利算法dfs模板 [二分图][二分图最大匹配]

最近学了二分图最大匹配,bfs模板却死活打不出来?我可能学了假的bfs 于是用到了dfs模板 寻找二分图最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是寻找增广路 寻找增光路是过程是:从一个未经配对的点出发,历经未配边.匹配边.未配边.匹配边.未配边....最终到达一个未配点的过程,只要把路径中的未配边和匹配边的“身份”对调,匹配就加一了.这就是一个寻找增广路的过程,通过不断寻找增广路,可以找到最大的匹配. 1 #include<cstdio> 2 #include<cstring&g

(匈牙利算法DFS)hdu 3729

I'm Telling the Truth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1542    Accepted Submission(s): 769 Problem Description After this year’s college-entrance exam, the teacher did a survey in

二分图最大匹配(匈牙利算法Dfs模板)

#include<iostream> #include<cstdio> #include<cstring> #define maxn 2020 using namespace std; int n,m,g[maxn][maxn],ans,f[maxn],match[maxn]; int init() { int x=0;char s;s=getchar(); while(s<'0'||s>'9')s=getchar(); while(s>='0'&am

棋盘覆盖及匈牙利算法

题目描述 Description 给出一张n*n(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖. 输入描述 Input Description 第一行为n,m(表示有m个删除的格子)第二行到m+1行为x,y,分别表示删除格子所在的位置x为第x行y为第y列 输出描述 Output Description 一个数,即最大覆盖格数 样例输入 Sample Input 8 0 样例输出 Sample Output 32 数据范围及提示 Data Size &am

&quot;《算法导论》之‘图’&quot;:不带权二分图最大匹配(匈牙利算法)

博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利算法 1. 前言 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图.准确地说:把一个图的顶点划分为两个不相交集 U 和V ,使得每一条边都分别连接U.V中的顶点.如果存在这样的划分,则此图为一个二分图.二分图的一个等价定义是:不含有「含奇数条边的环」的图.

(转)二分图的最大匹配、完美匹配和匈牙利算法

转载自http://www.renfei.org/blog/bipartite-matching.html 二分图的最大匹配.完美匹配和匈牙利算法 这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm):不讲带权二分图的最佳匹配. 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是

二分图的最大匹配、完美匹配和匈牙利算法(转)

转载自:http://blog.csdn.net/pi9nc/article/details/11848327 二分图的最大匹配.完美匹配和匈牙利算法 这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm):不讲带权二分图的最佳匹配. 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这

二分图的最大匹配、完美匹配和匈牙利算法

这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm):不讲带权二分图的最佳匹配. 二分图:简单来说,假设图中点能够被分为两组.而且使得全部边都跨越组的边界,则这就是一个二分图.准确地说:把一个图的顶点划分为两个不相交集 U和V .使得每一条边都分别连接U.V中的顶点. 假设存在这种划分,则此图为一个二分图.二分

二分图最大匹配——匈牙利算法

这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm):不讲带权二分图的最佳匹配. 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图.准确地说:把一个图的顶点划分为两个不相交集 U  和 V ,使得每一条边都分别连接U . V  中的顶点.如果存在这样的划分,则此图为一