SRM 582
来源:互联网 发布:我的世界linux服务端 编辑:程序博客网 时间:2024/06/16 17:56
250:最大的最小,最小的最大之类的题。。二分+验证
600:是个好题,整了好几天才整明白。
题意: 给你n个数1 2 3。。n,代表n个楼,每个数有一种颜色,数值就代表building的高度,现在问有多少的排列满足从左往右看能看到L种颜色。
n <= 1300,显然复杂度应该是平方级别的。
考虑从小到大一个个的占坑,dp[i][j]表示前i个数占完坑后,能看到j种颜色的方案数
显然,一个状态若是合法,应该使得后面的数插进来后是这个状态的延续,比如i j 这两维都应该是非递减的,其实就是i这个数前面不应该有空位了,否则这个空位会被后面的比较大的数占据,然后就破坏了原来的这个状态。
转移起来就是
dp[i][j] = dp[p][?] * A(n - 1 - p, i - p - 1);
用部分和来优化这个dp即可,注意dp[i][1]状态的初始化。
#include <cstdlib>#include <cctype>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <iostream>#include <sstream>#include <map>#include <set>#include <queue>#include <stack>#include <ctime>using namespace std;class ColorfulBuilding{public: int count(vector <string> color1, vector <string> color2, int L); };const int N = 1300;const int mod = 1000000009;int dp[N][N], cid[N], col[N], val[N][N], sum[N];int P[N], inv_P[N];int power_mod(long long a,long long b,long long c) { long long res = 1; while(b > 0) { if(b & 1) res = res * a % c; b >>= 1; a = a * a % c; } return (int) res;}inline void Add(int &x,int y) { x += y; if(x >= mod) x -= mod;}int ColorfulBuilding::count(vector <string> color1, vector <string> color2, int L){ string s1 = "", s2 = ""; for(int i = 0; i < color1.size(); i++) s1 += color1[i]; for(int i = 0; i < color2.size(); i++) s2 += color2[i]; map<int,int> mp; int totColor = 0; for(int i = 0; i < s1.length(); i++) { col[i + 1] = s1[i] * 256 + s2[i]; if(mp[col[i + 1]] == 0) mp[col[i + 1]] = ++totColor; col[i + 1] = mp[col[i + 1]]; } int n = s1.length(); inv_P[0] = 1; P[0] = 1; for(int i = 1; i <= n; i++) { P[i] = 1LL * P[i - 1] * i % mod; inv_P[i] = 1LL * inv_P[i - 1] * power_mod(i, mod - 2, mod) % mod; } memset(dp, 0, sizeof(dp)); memset(val, 0, sizeof(val)); memset(sum, 0, sizeof(sum)); for(int i = 1; i <= n; i++) { for(int j = 1; j <= i && j <= L; j++) { int add; if(j == 1) { add = 1LL * P[n - 1] * inv_P[n - i] % mod; Add(add, 1LL * val[col[i]][j] * inv_P[n - i] % mod); } else { add = sum[j - 1] - val[col[i]][j - 1]; if(add < 0) add += mod; Add(add, val[col[i]][j]); add = 1LL * add * inv_P[n - i] % mod; } dp[i][j] = add; if(i < n) { add = 1LL * dp[i][j] * P[n - i - 1] % mod; Add(sum[j], add); Add(val[col[i]][j], add); } } } return dp[n][L];}// Powered by FileEdit// Powered by TZTester 1.01 [25-Feb-2003]// Powered by CodeProcessor
1 0
- SRM 582
- srm
- 记首次参加TopCoder SRM Match,SRM 582
- TopCoder SRM 582 DIV2 250
- Topcoder SRM 582 DIV2 500
- SRM 582 Div II Level Two SpaceWarDiv2
- topcode srm SRM 557
- SRM 582 Div II Level Three: ColorTheCells, Brute Force 算法
- SRM 443
- SRM 442
- SRM 439
- SRM 438
- SRM 444
- SRM 434
- SRM 445
- SRM 426
- SRM 456
- SRM 467
- About Oracle Database
- python文件操作
- android ListView 的 setOnItemClickListener方法失效解决方法
- 数位dp模板
- 设计模式(1)-状态模式(C++)
- SRM 582
- 新起点?!
- 安装LAMP(CentOS6.6)
- 循环矩阵
- hdu 2089 数位dp模板题
- algorithm and data structure
- hdu 3555 数位dp模板题
- 如何下载Google Play上的APK?
- 学习炒汇的感受