【log】近期刷题 - 2015.9 - 2015.10
来源:互联网 发布:m2数据 2016 编辑:程序博客网 时间:2024/05/16 23:36
2015 沈阳赛区网络赛
hdu 5456 Matches Puzzle Game
从低位到高位dp,每次枚举 B,C,维护借位,还有B,C是否到达最高位。
dp(剩余火柴数,是否需要借位,B是否到达最高位,C是否到达最高位)
const int N = 500;const int num[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};LL dp[N+5][2][2][2], Mod;inline void add_mod(LL& x, LL y) { x += y; if ( x >= Mod ) x -= Mod;}LL go(int n, int carry, int b, int c) { if ( n == 0 ) { if ( carry ) return 0; if ( !b || !c ) return 0; return 1; } LL& ret = dp[n][carry][b][c]; if ( ret != -1 ) return ret; ret = 0; LL sum; int a; if ( b ) { if ( c ) { if ( carry ) add_mod(ret, go(n - num[carry], 0, 1, 1)); else return 0; } else { for (int i = 0; i <= 9; ++ i) { a = i + carry; sum = num[i] + num[ a % 10 ]; if ( sum <= n ) { add_mod(ret, go(n - sum, a / 10, 1, 0)); if ( i != 0 ) add_mod(ret, go(n - sum, a / 10, 1, 1)); } } } } else { if ( c ) { for (int i = 0; i <= 9; ++ i) { a = i + carry; sum = num[i] + num[ a % 10 ]; if ( sum <= n ) { add_mod(ret, go(n - sum, a / 10, 0, 1)); if ( i != 0 ) add_mod(ret, go(n - sum, a / 10, 1, 1)); } } } else { for (int i = 0; i <= 9; ++ i) for (int j = 0; j <= 9; ++ j) { a = i + j + carry; sum = num[i] + num[j] + num[ a % 10 ]; if ( sum <= n ) { add_mod(ret, go(n - sum, a / 10, 0, 0)); if ( i != 0 ) add_mod(ret, go(n - sum, a / 10, 1, 0)); if ( j != 0 ) add_mod(ret, go(n - sum, a / 10, 0, 1)); if ( i != 0 && j != 0 ) add_mod(ret, go(n - sum, a / 10, 1, 1)); } } } } return ret;}
FOJ有奖月赛-2015年10月
G
http://acm.fzu.edu.cn/problem.php?pid=2204
一行上有n个球,可以染成黑或白,要求连续7个不能是同样颜色,求方案数
(开始的颜色,前i个球,最后的段长为j,最后一段的颜色)
然后,枚举最开始放黑或白,进行dp预处理
对
枚举第一段的长度,最后一段的长度,分情况讨论,累加答案。
优化:因为第一个位置放黑白是对称的,所以可以让第一个位置固定为白色,然后得到的答案乘2
int dp[N+5][10][2];void add_mod(int& x, int y) { x += y; if ( x >= Mod ) x -= Mod;}void init(int n) { memset(dp, 0, sizeof(dp)); dp[1][1][0] = 1; for(int i = 1; i < n; ++ i) for(int j = 1; j <= 6; ++ j) if ( j <= i ) for (int k = 0; k <= 1; ++ k) if ( dp[i][j][k] ) { add_mod(dp[i+1][1][!k], dp[i][j][k]); add_mod(dp[i+1][j+1][k], dp[i][j][k]); }}int main() { init(N); int t, cas = 0; scanf("%d", &t); while ( t -- ) { int n; scanf("%d", &n); int ans = 0; if ( n < 7 ) { ans = (1 << n); } else { for (int k = 1; k <= 6; ++ k) { for (int i = 1; i <= 6; ++ i) if ( i <= n - k ) { add_mod(ans, dp[n-k][i][0]); } for(int i = 1; k + i <= 6; ++ i) if ( i <= n - k ) { add_mod(ans, dp[n-k][i][1]); } } add_mod(ans, ans); } printf("Case #%d: %d\n", ++ cas, ans); } return 0;}
POJ 2763 Housewife Wind
题意:
给一棵树,边上有权值。两种操作,1)询问两点间路径权值和 2)修改一条边的值
思路:
从《挑战程序设计竞赛》上学到 LCA + 树状数组的解法。
利用 RMQ LCA 中求出的欧拉序列,加上树状数组,可以方便的维护路径和。
void dfs(int fa, int u, int d) { // father, now, depth vs[timer] = u; // 记录欧拉序列 id[u] = timer; // 每个顶点在欧拉序列中的最小下标 dep[timer ++] = d; // 欧拉序列中每个下标对应深度 // 每条边在欧拉序列中对应一个区间, in[], out[] 分别是左右端点 // 当沿着这条边进入一颗子树的时候,需要加上该边权值 // 当沿着这条边离开子树的时候,要减去该边权值 for(int i = head[u]; i != -1; i = E[i].nxt) { const Edge& e = E[i]; if ( e.v == fa ) continue; BIT::upd(timer, w[e.id], n << 1); in[e.id] = timer; dfs(u, e.v, d+1); vs[timer] = u; BIT::upd(timer, -w[e.id], n << 1); out[e.id] = timer; dep[timer ++] = d; }}
代码
容斥练习
hdu 2204 Eddy’s爱好
题意:求 1 - n 中可以表示成
f(k) : 可以表示成
可以通过容斥求出答案
例如
最后对每个数,都只计了
关于 f(k) 的计算,可以用 f(k) = floor ( pow( n, 1.0 / k + eps ) )
而 acdreamer 给了一种更准确的方法
const int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};ll n, ans, tot;ll get(int k) { ll ret = pow(n, 1.0 / k) + 1e-8; -- ret; return ret;}void dfs(int cnt, int pos, int mul) { if ( cnt ) { ans += get(mul) * ( ( cnt & 1 ) ? 1 : -1 ); } if ( cnt == 3 ) return; for(int i = pos + 1; i < tot; ++ i) { if ( mul * prime[i] >= 60 ) break; dfs( cnt + 1, i, mul * prime[i] ); }}int main() { tot = sizeof(prime) / sizeof(int); while ( cin >> n ) { ans = 0; dfs(0, -1, 1); cout << ans + 1 << endl; } return 0;}
codeforces 588D - Duff in Beach
bi 可以表示成
{0…n-1}{0…n-1}{0…(l%n - 1 + n) % n} 括号中的数字是 ai 中的下标,每个括号中的元素为一段
(i, j) 表示从第0段开始长度为i,以ai中下标为j的元素结束
然后对每个(i, j)算出起始段的可行个数 x,将 x * dp(i, j) 增加到答案。
PS:有爆ll的点。。
- 【log】近期刷题 - 2015.9 - 2015.10
- 近期刷题题解
- 【总结】队内互测 + 近期刷题
- 近期刷题的c语言总结。
- 近期笔试题小结
- 近期笔试题回顾
- 近期。
- 近期
- 近期
- 近期
- 近期
- 近期
- 近期
- 近期
- 近期开始以刷通USACAO为主。
- 近期笔试题C/C++---1
- 近期笔试题C/C++---2
- 针对近期实习笔试题的看法
- Git配置过程中出现的问题,以及解决方案
- mysql 存在update不存在insert
- 修改系统AlertDialog样式、自定义Dailog-----Activity透明效果
- iOS消息推送机制的实现
- 缺陷管理工具整理
- 【log】近期刷题 - 2015.9 - 2015.10
- C语言实验——某年某月的天数
- lubuntu vi/vim 使用系统粘贴版
- ReactiveCocoa2实战
- linux /etc/hosts文件作用
- [MFC]文档字符串、HKEY_CLASSES_ROOT注册表、.reg注册表文件
- visio 2007:方向键无法移动图像解决方法
- Android基础:数据存储(一):文件存储的工具类UtilsFile
- 相似图片搜索的原理(二)