250pt
题意:给定一个[0,1)间的实数,一个分母不超过maxDen的分数逼近。。
思路:直接枚举。然后判断。
code:
1 #line 7 "BestApproximationDiv1.cpp" 2 #include <cstdlib> 3 #include <cctype> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <vector> 9 #include <string> 10 #include <iostream> 11 #include <sstream> 12 #include <map> 13 #include <set> 14 #include <queue> 15 #include <stack> 16 #include <fstream> 17 #include <numeric> 18 #include <iomanip> 19 #include <bitset> 20 #include <list> 21 #include <stdexcept> 22 #include <functional> 23 #include <utility> 24 #include <ctime> 25 using namespace std; 26 27 #define PB push_back 28 #define MP make_pair 29 #define eps 1e-9 30 #define REP(i,n) for(i=0;i<(n);++i) 31 #define FOR(i,l,h) for(i=(l);i<=(h);++i) 32 #define FORD(i,h,l) for(i=(h);i>=(l);--i) 33 34 typedef vector<int> VI; 35 typedef vector<string> VS; 36 typedef vector<double> VD; 37 typedef long long LL; 38 typedef pair<int,int> PII; 39 40 41 class BestApproximationDiv1 42 { 43 public: 44 string findFraction(int maxDen, string number) 45 { 46 int A = 0, B = 100000, C = 1; 47 for (int i = 1; i <= maxDen; ++i) 48 for (int j = 0; j < i; ++j){ 49 double tmp = (j + .0) / (i + .0) + eps; 50 int cnt = 1; 51 // if (i == 7 && j == 1){ 52 // cout << "fuck" << endl; 53 // } 54 for (int k = 0; k < 6; ++k){ 55 tmp *= 10; 56 int x = floor(tmp); 57 tmp -= x; 58 if (x == number[k+2]-48) ++cnt; 59 else break; 60 } 61 if (cnt > C || (cnt == C && i < B)){ 62 C = cnt; 63 A = j; 64 B = i; 65 } 66 } 67 string res(""), s; 68 stringstream ss; 69 ss << A; 70 ss >> s; 71 res += s + "/"; 72 ss.clear(); 73 ss << B; 74 ss >> s; 75 res += s; 76 res += " has "; 77 ss.clear(); 78 ss << C; 79 ss >> s; 80 res += s; 81 res += " exact digits"; 82 return res; 83 } 84 };
500pt
题意:n<=50 个人排成1排,每个人都有一个抵抗值和影响力(均小于500),如果收买第i个人,那么跟他距离为k抵抗值的值减少influence[i] / 2^k。
求最少收买都少人,使得每个人的抵抗值降为0.
思路:刚开始确实往最大流甚至费用流想了。不过想了好久还是没想到怎么做。。
后来看了题解才知道是dp。并且突破口是每个人最多影响他旁边的8个人(当然,也就最多左右8个人影响到他)
所以,我们可以预处理出一个数组can[i][1 << 17]表示以i为中心的17个人的状态一直的情况下,第i个人是否抵抗值降为小于等于0
那么我们设dp[i][mask]表示第i个人为中心的17个人的状态为mask情况下最少安排多少人
那么我们就可以用dp[i][mask]转移到dp[i+1][mask>>1] 和dp[i+1][mask>>1|(1 << 16)](前提是can[i+1][mask>>1]和dp[i+1][mask>>1|(1 << 16)]为true)
code:
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "TreesCount.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <string> 15 #include <iostream> 16 #include <sstream> 17 #include <map> 18 #include <set> 19 #include <queue> 20 #include <stack> 21 #include <fstream> 22 #include <numeric> 23 #include <iomanip> 24 #include <bitset> 25 #include <list> 26 #include <stdexcept> 27 #include <functional> 28 #include <utility> 29 #include <ctime> 30 using namespace std; 31 #define PB push_back 32 #define MP make_pair 33 #define Inf 0x3fffffff 34 #define REP(i,n) for(i=0;i<(n);++i) 35 #define FOR(i,l,h) for(i=(l);i<=(h);++i) 36 #define FORD(i,h,l) for(i=(h);i>=(l);--i) 37 #define M 1000000007 38 typedef vector<int> VI; 39 typedef vector<string> VS; 40 typedef vector<double> VD; 41 typedef long long LL; 42 typedef pair<int,int> PII; 43 44 45 class TreesCount 46 { 47 public: 48 int d[120], dg[120]; 49 bool v[120]; 50 int count(vector <string> S) 51 { 52 int n = S.size(); 53 memset(dg, 0 , sizeof(dg)); 54 memset(v, 0, sizeof(v)); 55 for (int i = 0; i < n; ++i) d[i] = Inf; 56 queue<int> q; 57 q.push(0); 58 d[0] = 0; 59 dg[0] = 1; 60 v[0] = true; 61 int x, dst; 62 while (!q.empty()){ 63 x = q.front(); 64 for (int y = 0; y < n; ++y){ 65 dst = S[x][y] - '0'; 66 if (dst > 0 && d[x] + dst <= d[y]){ 67 if (d[x] + dst < d[y]){ 68 dg[y] = 1; 69 d[y] = d[x] + dst; 70 if (!v[y]) q.push(y), v[y] = true; 71 } 72 else ++dg[y]; 73 } 74 } 75 v[x] = false; 76 q.pop(); 77 } 78 long long ans = 1; 79 for (int i = 0; i < n; ++i) 80 ans = (ans * dg[i]) % M; 81 return ans; 82 } 83 84 };