cugb.20140417 (ural 1961 - 1970)
2014-04-18 13:38
330 查看
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=44276#overview
http://acm.timus.ru/problemset.aspx?space=1&page=10 uarl 1961-1970
C(M, m) * C(N-M, n-m) / C(N, n) >= C(M, m+1) * C(N-M, n-m-1) / C(N, n)
分成几个group,如果有圈,那么如果有1个group答案就是2,否则就是0。但是要特判n==2 , 答案就是1
如果每个group都是链,就是乘起来(group里面有1个点就是乘以1否则乘以2),再乘以group的组合数,由于1固定所以乘以(group-1)!
http://acm.timus.ru/problemset.aspx?space=1&page=10 uarl 1961-1970
A
problem
think
C(M, m) * C(N-M, n-m) / C(N, n) >= C(M, m-1) * C(N-M, n-m+1) / C(N, n)C(M, m) * C(N-M, n-m) / C(N, n) >= C(M, m+1) * C(N-M, n-m-1) / C(N, n)
code
cin >> n >> m >> N; M = min(N, (m * N + m) / n); cout<<M<<endl;
B...In Chinese Restaurant
problem
给你n和m,n个人,前m个人要和第ki个人挨着(i!=ki),做成一个圈,1的位置固定,求方案数 n <= 100think
给的m个人的需求,建立双向边,每个人的度最多是2,否则答案是0.分成几个group,如果有圈,那么如果有1个group答案就是2,否则就是0。但是要特判n==2 , 答案就是1
如果每个group都是链,就是乘起来(group里面有1个点就是乘以1否则乘以2),再乘以group的组合数,由于1固定所以乘以(group-1)!
code
const LL mod = 1000000007; const int N = 111; int lft , rit ; int vis ; LL A ; bool quan; int dfs(int s, int pre, int now){ if(vis[s] != 0){ quan = true; return 2; } vis[s] = now; if(lft[s] == -1 && rit[s] == -1) return 1; if(lft[s] != -1 && lft[s] != pre) dfs(lft[s], s, now); if(rit[s] != -1 && rit[s] != pre) dfs(rit[s], s, now); return 2; } int main(){ int n, m; A[0] = 1LL; for(int i = 1; i <= 100; ++i) A[i] = A[i-1]*i % mod; while(scanf("%d%d", &n, &m) != EOF){ memset(lft, -1, sizeof(lft)); memset(rit, -1, sizeof(rit)); bool nop = false; for(int i = 1; i <= m; ++i){ int a; scanf("%d", &a); if(lft[i] != a && rit[i] != a){ if(lft[i] == -1) lft[i] = a; else if(rit[i] == -1) rit[i] = a; else nop = true; } if(lft[a] != i && rit[a] != i){ if(lft[a] == -1) lft[a] = i; else if(rit[a] == -1) rit[a] = i; else nop = true; } } if(nop){ puts("0"); continue; } if(n==2){ puts("1"); continue; } memset(vis, 0, sizeof(vis)); int now = 0; LL ans = 1LL; quan = false; for(int i = 1; i <= n; ++i){ if(vis[i] == 0){ ans *= (LL)dfs(i, 0, ++now); ans %= mod; } } ans *= A[now-1]; ans %= mod; if(quan && now > 1) puts("0"); else printf("%I64d\n", ans); } return 0; }
E.Pear Tree
problem
给你一个由1-n组成的一种排列方式,n是1e5,问你能不能拆成两个序列,使得两个序列都是单调的。能的话就输出任意一种方案。think
瞪着别人的没有注释代码看了好几天。原来一遍又一遍重复又重复之后突然之间,会开窍。code
/** 第二维:0表示上升序列,1表示下降序列 第0位表示a[i]在的那个序列,第1位表示另一个序列 如:01表示a[i]在的序列下降另一个序列上升 is[i][j]表示a[i]放在序列的id,0|1 dp[i][j]表示另一个(a[i]不在的那个序列)序列的目前最后一个数 [i,j]状态是由[i-1, pre[i][j]]状态转移过来的, is和pre是为了最后输出结果 **/ const int N = 111111; int dp [4]; int is [4]; int pre [4]; int a ; vector<int>ans[2]; int main(){ int n; while(scanf("%d", &n) != EOF){ memset(dp, -1, sizeof(dp)); dp[0][0] = dp[0][1] = 0;//第二个序列是上升的 dp[0][2] = dp[0][3] = N; ans[0].clear(); ans[1].clear(); for(int i = 0; i < n; ++i) scanf("%d", &a[i]); for(int i = 0; i < n - 1; ++i){ for(int j = 0; j < 4; ++j){ if(dp[i][j] == -1) continue; bool fi = j & 1; bool se = j >> 1; if((a[i+1] > a[i]) ^ fi){//a[i+1]放在和a[i]相同的序列 if(dp[i+1][j] == -1 || ((dp[i+1][j] > dp[i][j])^se)){//放了会使状态变得更优 dp[i+1][j] = dp[i][j]; is[i+1][j] = is[i][j]; pre[i+1][j] = j; } } if((a[i+1] > dp[i][j]) ^ se){ int jj = ((int)fi << 1) | se; if(dp[i+1][jj] == -1 || ((dp[i+1][jj] > a[i]) ^ fi)){ dp[i+1][jj] = a[i]; is[i+1][jj] = is[i][j] ^ 1; pre[i+1][jj] = j; } } } } for(int j = 0; j < 4; ++j) if(dp[n-1][j] != -1){ int jj = j; for(int i = n-1; i >= 0; --i){ ans[is[i][jj]].push_back(a[i]); jj = pre[i][jj]; } break; } if(ans[0].size() == 0){ if(ans[1].size() == 0) puts("Fail"); else{ printf("%d %d\n%d\n%d", 1, n-1, ans[1][n-1], ans[1][n-2]); for(int i = n-3; i >= 0; --i) printf(" %d", ans[1][i]); puts(""); } } else if(ans[1].size() == 0){ printf("%d %d\n%d\n%d", 1, n-1, ans[0][n-1], ans[0][n-2]); for(int i = n-3; i >= 0; --i) printf(" %d", ans[0][i]); puts(""); } else{ printf("%d %d\n", ans[0].size(), ans[1].size()); printf("%d", ans[0][ans[0].size()-1]); for(int i = ans[0].size() - 2; i >= 0; --i) printf(" %d", ans[0][i]); puts(""); printf("%d", ans[1][ans[1].size()-1]); for(int i = ans[1].size() - 2; i >= 0; --i) printf(" %d", ans[1][i]); puts(""); } } return 0; }
J...皇后像廣場
problem
think
暴力回溯dfs竟然过了。。code
int a[9][4][4][4];//9个方块,4个方向,4*4的元素 bool lft[9][4][9][4]; bool down[9][4][9][4]; int vis[10]; int zhu1[10];//用于存哪个方块 int zhu2[10];//用于存哪个方向 bool can(int n, int i, int ii){ if(vis[i]) return false; if(n >= 3 && !down[zhu1[n-3]][zhu2[n-3]][i][ii]) return false; if(n%3 > 0 && !lft[zhu1[n-1]][zhu2[n-1]][i][ii]){ return false; } return true; } bool dfs(int n){ if(n == 9){ for(int i = 0; i < 10; ++i){ for(int j = 0; j < 10; ++j){ if(i <= 2){ if(j <= 2) printf("%d ", a[zhu1[0]][zhu2[0]][i][j]); else if(j <= 5) printf("%d ", a[zhu1[1]][zhu2[1]][i][j-3]); else if(j <= 8) printf("%d ", a[zhu1[2]][zhu2[2]][i][j-6]); else printf("%d\n", a[zhu1[2]][zhu2[2]][i][j-6]); } else if(i <= 5){ if(j <= 2) printf("%d ", a[zhu1[3]][zhu2[3]][i-3][j]); else if(j <= 5) printf("%d ", a[zhu1[4]][zhu2[4]][i-3][j-3]); else if(j <= 8) printf("%d ", a[zhu1[5]][zhu2[5]][i-3][j-6]); else printf("%d\n", a[zhu1[5]][zhu2[5]][i-3][j-6]); } else if(i <= 9){ if(j <= 2) printf("%d ", a[zhu1[6]][zhu2[6]][i-6][j]); else if(j <= 5) printf("%d ", a[zhu1[7]][zhu2[7]][i-6][j-3]); else if(j <= 8) printf("%d ", a[zhu1[8]][zhu2[8]][i-6][j-6]); else printf("%d\n", a[zhu1[8]][zhu2[8]][i-6][j-6]); } } } return true; } for(int i = 0; i < 9; ++i) for(int ii = 0; ii < 4; ++ii){ if(can(n, i, ii)){ vis[i] = 1; zhu1 = i; zhu2 = ii; if(dfs(n+1)) return true; vis[i] = 0; } } return false; } int main(){ for(int i = 0; i < 9; ++i){ for(int j = 0; j < 4; ++j){ for(int k = 0; k < 4; ++k){ scanf("%d", &a[i][0][j][k]); } } for(int h = 1; h <= 3; ++h){ for(int j = 0; j < 4; ++j){ for(int k = 0; k < 4; ++k){ a[i][h][3-k][j] = a[i][h-1][j][k]; } } } } for(int i = 0; i < 9; ++i) for(int ii = 0; ii < 4; ++ii) { for(int j = 0; j < 9; ++j) for(int jj = 0; jj < 4; ++jj) { if(i != j){ bool ok1 = 1; bool ok2 = 1; for(int k = 0; k < 4; ++k){ ok1 &= (a[i][ii][3][k] == a[j][jj][0][k]); ok2 &= (a[i][ii][k][3] == a[j][jj][k][0]); } down[i][ii][j][jj] = ok1; lft[i][ii][j][jj] = ok2; } } } memset(vis, 0, sizeof(vis)); dfs(0); return 0; }
相关文章推荐
- URAL 1970 J - 皇后像廣場 dfs
- URAL1961:Cantonese Dialect
- URAL 1970 皇后像廣場 暴力搜索
- Ural 1961 Cantonese Dialect
- URAL 1639. Chocolate 2
- URAL 1502. Domino Dots(数学)
- URAL 1057 数位DP
- URAL_1789_Searching for the Dodecahedron_机智
- ural1297 Palindrome【后缀数组】
- 递推DP URAL 1009 K-based Numbers
- 01背包 URAL 1073 Square Country
- DP+高精度 URAL 1036 Lucky Tickets
- Ural 1225 Flags
- Ural 1167 Bicolored Horses
- URAL 1457. Heating Main
- URAL 1502. Domino Dots (找规律)
- URAL 1180. Stone Game (博弈 + 规律)
- Ural - 1057. Amount of Degrees
- URAL - 1519 Formula 1 (插头DP)
- URAL 1934 最短路变形