Codeforces #315 div1
2015-08-11 03:22:39
【传送门】
总结:由于实验室网络不稳定... 跑到宿舍楼下自习室打的...
最近一直在补多校、刷图论数论,脑子有点僵... DP很久没刷,深感dp实力下降,在之前的BC中就已经体现出来了,第二道水DP竟然还debug了10min TUT。
今天这场也算是敲醒了dp警钟。
A题:这题出的怪怪的,暴力打表... 没啥好说的,注意 long long。
#include <cstdio> #include <ctime> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <string> #include <iostream> #include <algorithm> using namespace std; #define getmid(l,r) ((l) + ((r) - (l)) / 2) #define MP(a,b) make_pair(a,b) #define PB push_back typedef long long ll; typedef pair<int,int> pii; const double eps = 1e-8; const int INF = (1 << 30) - 1; int prime[2000010]; int pal[2000010]; bool P(int v){ int k = sqrt(1.0 * v); for(int i = 2; i <= k; ++i) if(v % i == 0) return false; return true; } int s[10]; bool PA(int v){ int cnt = 0; while(v){ s[++cnt] = v % 10; v /= 10; } for(int i = 1; i <= cnt; ++i) if(s[i] != s[cnt + 1 - i]) return false; return true; } int main(){ pal[1] = 1; prime[1] = 0; for(int i = 2; i <= 2000000; ++i){ if(P(i)) prime[i] = 1; if(PA(i)) pal[i] = 1; prime[i] += prime[i - 1]; pal[i] += pal[i - 1]; } int p,q; scanf("%d%d",&p,&q); int ans = 0; for(int i = 1; i <= 2000000; ++i){ ll A = 1ll * prime[i] * q; ll B = 1ll * pal[i] * p; if(A <= B) ans = i; } printf("%d\n",ans); return 0; }
B题:DP
题意:比较难懂,简单来说就是总共n(<=4000)个点,你要挑选一些点放进一个集合(不能全选),这些点在集合中形成若干个联通块,问总共有多少种图。
早早地想到DP,换了两三个思路... 一直不知道怎么算联通块形成种类数。比赛中WA了6发没过 - -!赛后问了Jay巨,发现自己太young了....
思路:可以枚举没被放入集合的点数,设为 i,再设 DP[i] 为 i 个点放入集合形成若干联通块的图的方案数,设 dp[i][j] 为 i 个点形成 j 个联通块的方案数。
那么:dp[i][j] = dp[i - 1][j] * j + dp[i - 1][j - 1] , DP[i] = Sigma(dp[i][j]) , (1 <= j <= i)。
最后的答案就是:Sigma( C( n , i ) * DP[n - i] ) , ( 1 <= i <= n )
#include <cstdio> #include <ctime> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <string> #include <iostream> #include <algorithm> using namespace std; #define getmid(l,r) ((l) + ((r) - (l)) / 2) #define MP(a,b) make_pair(a,b) #define PB push_back typedef long long ll; typedef pair<int,int> pii; const double eps = 1e-8; const int INF = (1 << 30) - 1; const ll mod = 1e9 + 7; int n; ll dp[4010][4010],DP[4010]; ll C[4010][4010]; void Pre(){ for(int i = 0; i <= 4000; ++i){ C[i][0] = C[i][i] = 1; for(int j = 1; j < i; ++j){ C[i][j] = C[i - 1][j] + C[i - 1][j - 1]; C[i][j] %= mod; } } } int main(){ Pre(); scanf("%d",&n); dp[0][0] = 1; DP[0] = 1; for(int i = 1; i <= n; ++i){ for(int j = 1; j <= i; ++j){ dp[i][j] = dp[i - 1][j] * j + dp[i - 1][j - 1]; dp[i][j] %= mod; DP[i] += dp[i][j]; DP[i] %= mod; } } ll ans = 0; for(int i = 1; i <= n; ++i){ ans += C[n][i] * DP[n - i]; ans %= mod; } printf("%I64d\n",ans); return 0; }