USACO 之 Section 2.3 (已解决)
Longest Prefix:
/*
dp:
dp[i] := 第i个位置是否继续可放集合里面的某一个元素(数组从0开始编号)
dp[i + len(集合里面的元素)] = true
初始化:dp[0] = true
答案:dp数组从S.size()位置开始,向前遍历,如果dp[i] = true,i即为答案。
*/
1 /* 2 ID: Jming 3 PROG: prefix 4 LANG: C++ 5 */ 6 #include <iostream> 7 #include <fstream> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstdio> 11 #include <cstddef> 12 #include <iterator> 13 #include <algorithm> 14 #include <string> 15 #include <locale> 16 #include <cmath> 17 #include <vector> 18 #include <cstring> 19 #include <map> 20 #include <utility> 21 #include <queue> 22 #include <stack> 23 #include <set> 24 #include <bitset> 25 #include <functional> 26 #include <cassert> 27 using namespace std; 28 typedef pair<int, int> PII; 29 typedef long long int64; 30 const int INF = 0x3f3f3f3f; 31 const int modPrime = 3046721; 32 const double eps = 1e-9; 33 const int MaxN = 200010; 34 const int MaxM = 20; 35 36 bool dp[MaxN]; 37 vector<string> vecStr; 38 string S; 39 40 void Solve() 41 { 42 fill(dp, dp + MaxN, false); 43 dp[0] = true; 44 for (int i = 0; i < S.size(); ++i) 45 { 46 if (dp[i]) 47 { 48 for (int j = 0; j < vecStr.size(); ++j) 49 { 50 int k = 0; 51 for (; k < vecStr[j].size(); ++k) 52 { 53 if (S[k + i] != vecStr[j][k]) 54 { 55 break; 56 } 57 } 58 if (vecStr[j].size() == k) 59 { 60 dp[i + vecStr[j].size()] = true; 61 int a = 0; 62 } 63 } 64 } 65 } 66 for (int i = S.size(); i >= 0; --i) 67 { 68 if (dp[i]) 69 { 70 cout << i << endl; 71 return; 72 } 73 } 74 } 75 76 77 int main() 78 { 79 #ifdef HOME 80 freopen("in", "r", stdin); 81 //freopen("out", "w", stdout); 82 #endif 83 84 freopen("prefix.in", "r", stdin); 85 freopen("prefix.out", "w", stdout); 86 87 string inStr; 88 while ((cin >> inStr) && ("." != inStr)) 89 { 90 vecStr.push_back(inStr); 91 } 92 while (cin >> inStr) 93 { 94 S += inStr; 95 } 96 Solve(); 97 98 99 #ifdef HOME 100 cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl; 101 #endif 102 return 0; 103 }
Cow Pedigrees:
/*
dp[i][j] := 在层数小于等于i,节点数恰为j的情况下,家谱树的个数。
dp[i][j] = ∑(dp[i-1][n] * dp[i-1][j-1-n])
即:∑(左子树*右子树)
初始化:dp[i][0] = 1
答案:
ans := 层数恰为K,节点数恰为N的情况下,家谱树的个数。
ans = dp[K][N] - dp[K-1][N]
*/
1 /* 2 ID: Jming 3 PROG: nocows 4 LANG: C++ 5 */ 6 #include <iostream> 7 #include <fstream> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstdio> 11 #include <cstddef> 12 #include <iterator> 13 #include <algorithm> 14 #include <string> 15 #include <locale> 16 #include <cmath> 17 #include <vector> 18 #include <cstring> 19 #include <map> 20 #include <utility> 21 #include <queue> 22 #include <stack> 23 #include <set> 24 #include <bitset> 25 #include <functional> 26 #include <cassert> 27 using namespace std; 28 typedef pair<int, int> PII; 29 typedef long long int64; 30 const int INF = 0x3f3f3f3f; 31 const int modPrime = 3046721; 32 const double eps = 1e-9; 33 const int MaxN = 210; 34 const int MaxK = 110; 35 const int Mod = 9901; 36 37 int N, K; 38 int dp[MaxK][MaxN]; 39 40 void Solve() 41 { 42 for (int i = 0; i <= K; ++i) 43 { 44 dp[i][0] = 1; 45 } 46 for (int i = 1; i <= K; ++i) 47 { 48 for (int j = 1; j <= N; j += 2) 49 { 50 for (int n = 0; n <= (j - 1); ++n) 51 { 52 dp[i][j] = (dp[i][j] + dp[i - 1][n] * dp[i - 1][j - 1 - n]) % Mod; 53 //cout << i << "层" << j << "个节点" << " ---> " << dp[i][j] << endl; 54 } 55 } 56 } 57 // 由于dp[K][N]取余之后,可能小于dp[K-1][N],所以先加Mod再取余。 58 cout << (dp[K][N] - dp[K - 1][N] + Mod)%Mod << endl; 59 } 60 61 62 int main() 63 { 64 #ifdef HOME 65 freopen("in", "r", stdin); 66 //freopen("out", "w", stdout); 67 #endif 68 69 freopen("nocows.in", "r", stdin); 70 freopen("nocows.out", "w", stdout); 71 72 cin >> N >> K; 73 Solve(); 74 75 76 #ifdef HOME 77 cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; 78 #endif 79 return 0; 80 }
Zero Sum:
/*
搜索即可
*/
1 /* 2 ID: Jming 3 PROG: zerosum 4 LANG: C++ 5 */ 6 #include <iostream> 7 #include <fstream> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstdio> 11 #include <cstddef> 12 #include <iterator> 13 #include <algorithm> 14 #include <string> 15 #include <locale> 16 #include <cmath> 17 #include <vector> 18 #include <cstring> 19 #include <map> 20 #include <utility> 21 #include <queue> 22 #include <stack> 23 #include <set> 24 #include <bitset> 25 #include <functional> 26 #include <cassert> 27 using namespace std; 28 typedef pair<int, int> PII; 29 typedef long long int64; 30 const int INF = 0x3f3f3f3f; 31 const int modPrime = 3046721; 32 const double eps = 1e-9; 33 const int MaxN = 210; 34 const int MaxK = 110; 35 const int Mod = 9901; 36 37 const char symbol[] = { '+', '-', ' ' }; 38 int N; 39 char arr[20]; 40 int arrLen; 41 vector<string> ans; 42 43 bool ZeroSum(string str) 44 { 45 str = "0+" + str; 46 int sum = str[0] - '0'; 47 int num = 0; 48 for (size_t i = 2; i < str.size(); i += 2) 49 { 50 num = str[i] - '0'; 51 char syb = str[i - 1]; 52 while ((i + 1 < str.size()) && (' ' == str[i + 1])) 53 { 54 num = num * 10 + (str[i + 2] - '0'); 55 i += 2; 56 } 57 switch (syb) 58 { 59 case '+': 60 { 61 sum += num; 62 break; 63 } 64 case '-': 65 { 66 sum -= num; 67 break; 68 } 69 default: 70 break; 71 } 72 } 73 return (0 == sum); 74 } 75 76 void Dfs(int pos) 77 { 78 if (pos == arrLen) 79 { 80 if (ZeroSum(arr)) 81 { 82 ans.push_back(arr); 83 } 84 return; 85 } 86 for (size_t j = 0; j < strlen(symbol); ++j) 87 { 88 arr[pos] = symbol[j]; 89 Dfs(pos + 2); 90 } 91 } 92 93 94 void Solve() 95 { 96 arrLen = ((N << 1) - 1); 97 int num = 1; 98 for (size_t i = 0; i < arrLen; i += 2) 99 { 100 arr[i] = ('0' + num); 101 ++num; 102 } 103 Dfs(1); 104 sort(ans.begin(), ans.end()); 105 for (size_t i = 0; i < ans.size(); ++i) 106 { 107 cout << ans[i] << endl; 108 } 109 } 110 111 112 int main() 113 { 114 #ifdef HOME 115 freopen("in", "r", stdin); 116 //freopen("out", "w", stdout); 117 #endif 118 119 freopen("zerosum.in", "r", stdin); 120 freopen("zerosum.out", "w", stdout); 121 122 cin >> N; 123 Solve(); 124 125 126 #ifdef HOME 127 std::cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; 128 #endif 129 return 0; 130 }
Money Systems:
/*
完全背包变形:(每个硬币都有无限个可用)
dp[i][j] := 前i种硬币,恰构造出j的方案数
dp[i][j] = dp[i-1][j] + dp[i][j-coin[i]]
*/
1 /* 2 ID: Jming 3 PROG: money 4 LANG: C++ 5 */ 6 #include <iostream> 7 #include <fstream> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstdio> 11 #include <cstddef> 12 #include <iterator> 13 #include <algorithm> 14 #include <string> 15 #include <locale> 16 #include <cmath> 17 #include <vector> 18 #include <cstring> 19 #include <map> 20 #include <utility> 21 #include <queue> 22 #include <stack> 23 #include <set> 24 #include <bitset> 25 #include <functional> 26 #include <cassert> 27 using namespace std; 28 typedef pair<int, int> PII; 29 typedef long long int64; 30 const int INF = 0x3f3f3f3f; 31 const int modPrime = 3046721; 32 const double eps = 1e-9; 33 const int MaxN = 10010; 34 const int MaxM = 110; 35 36 int V, N; 37 vector<int> availableCoins; 38 long long dp[MaxN]; 39 40 void Solve() 41 { 42 dp[0] = 1; 43 for (int i = 0; i < V; ++i) 44 { 45 for (int j = availableCoins[i]; j <= N; ++j) 46 { 47 dp[j] = dp[j] + dp[j - availableCoins[i]]; 48 } 49 /* 50 // 01背包写法 51 for (int j = N; j >= availableCoins[i]; --j) 52 { 53 for (int k = 1; k <= (j / availableCoins[i]); ++k) 54 { 55 dp[j] = dp[j] + dp[j - k*availableCoins[i]]; 56 } 57 } 58 */ 59 } 60 cout << dp[N] << endl; 61 } 62 63 int main() 64 { 65 #ifdef HOME 66 freopen("in", "r", stdin); 67 //freopen("out", "w", stdout); 68 #endif 69 70 freopen("money.in", "r", stdin); 71 freopen("money.out", "w", stdout); 72 73 cin >> V >> N; 74 int coin; 75 for (int i = 0; i < V; ++i) 76 { 77 cin >> coin; 78 availableCoins.push_back(coin); 79 } 80 Solve(); 81 82 #ifdef HOME 83 std::cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; 84 #endif 85 return 0; 86 }
Controlling Companies:
解法一:
/*
模拟控制公司的三个条件,逐渐更新公司之间控制的状态。
*/
1 /* 2 ID: Jming 3 PROG: concom 4 LANG: C++ 5 */ 6 #include <iostream> 7 #include <fstream> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstdio> 11 #include <cstddef> 12 #include <iterator> 13 #include <algorithm> 14 #include <string> 15 #include <locale> 16 #include <cmath> 17 #include <vector> 18 #include <cstring> 19 #include <map> 20 #include <utility> 21 #include <queue> 22 #include <stack> 23 #include <set> 24 #include <bitset> 25 #include <functional> 26 #include <cassert> 27 using namespace std; 28 typedef pair<int, int> PII; 29 typedef long long int64; 30 const int INF = 0x3f3f3f3f; 31 const int modPrime = 3046721; 32 const double eps = 1e-9; 33 const int MaxN = 110; 34 const int MaxM = 110; 35 36 int N; 37 bool controlling[MaxN][MaxN]; 38 int stock[MaxN][MaxN]; 39 40 void Solve() 41 { 42 bool updated = true; 43 while (updated) 44 { 45 updated = false; 46 /* 47 Company A controls K(K >= 1) companies denoted C1, ..., CK with 48 each company Ci owning xi% of company B and x1 + .... + xK > 50%. 49 */ 50 for (int i = 1; i < MaxN; ++i) 51 { 52 for (int j = 1; j < MaxN; ++j) 53 { 54 if (!controlling[i][j]) 55 { 56 int sum = 0; 57 for (int k = 1; k < MaxN; ++k) 58 { 59 if (controlling[i][k]) 60 { 61 sum += stock[k][j]; 62 } 63 } 64 if (sum > 50) 65 { 66 controlling[i][j] = true; 67 if (!updated) 68 { 69 updated = true; 70 } 71 } 72 } 73 } 74 } 75 } 76 for (int i = 1; i < MaxN; ++i) 77 { 78 for (int j = 1; j < MaxN; ++j) 79 { 80 if ((i != j) && controlling[i][j]) 81 { 82 cout << i << " " << j << endl; 83 } 84 } 85 } 86 } 87 88 int main() 89 { 90 #ifdef HOME 91 freopen("in", "r", stdin); 92 //freopen("out", "w", stdout); 93 #endif 94 95 freopen("concom.in", "r", stdin); 96 freopen("concom.out", "w", stdout); 97 98 memset(controlling, false, sizeof(controlling)); 99 100 // Company A = Company B 101 for (int i = 0; i < MaxN; ++i) 102 { 103 controlling[i][i] = true; 104 } 105 cin >> N; 106 int a, b; 107 for (int i = 0; i < N; ++i) 108 { 109 cin >> a >> b; 110 cin >> stock[a][b]; 111 // Company A owns more than 50 % of Company B 112 if (stock[a][b] > 50) 113 { 114 controlling[a][b] = true; 115 } 116 } 117 Solve(); 118 119 #ifdef HOME 120 std::cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; 121 #endif 122 return 0; 123 }
解法二(官方答案方法):
/*
两个步骤:
(1)添加 company A owning p% of company B
(2)添加 company A controls company B
*/
1 /* 2 ID: Jming 3 PROG: concom 4 LANG: C++ 5 */ 6 #include <iostream> 7 #include <fstream> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstdio> 11 #include <cstddef> 12 #include <iterator> 13 #include <algorithm> 14 #include <string> 15 #include <locale> 16 #include <cmath> 17 #include <vector> 18 #include <cstring> 19 #include <map> 20 #include <utility> 21 #include <queue> 22 #include <stack> 23 #include <set> 24 #include <bitset> 25 #include <functional> 26 #include <cassert> 27 using namespace std; 28 typedef pair<int, int> PII; 29 typedef long long int64; 30 const int INF = 0x3f3f3f3f; 31 const int modPrime = 3046721; 32 const double eps = 1e-9; 33 const int MaxN = 110; 34 const int MaxM = 110; 35 36 int N; 37 bool controlling[MaxN][MaxN]; 38 int own[MaxN][MaxN]; 39 40 // 添加 company A controls company B 41 void addControl(int a, int b) 42 { 43 if (controlling[a][b]) 44 { 45 return; 46 } 47 controlling[a][b] = true; 48 49 for (int i = 0; i < MaxN; ++i) 50 { 51 own[a][i] += own[b][i]; 52 } 53 54 // 控制A的公司,也可以控制公司B了 55 for (int i = 1; i < MaxN; ++i) 56 { 57 if (controlling[i][a]) 58 { 59 addControl(i, b); 60 } 61 } 62 63 // A控制更多的公司 64 for (int i = 1; i < MaxN; ++i) 65 { 66 if (own[a][i] > 50) 67 { 68 addControl(a, i); 69 } 70 } 71 } 72 73 // 添加 company A owning p% of company B 74 void addOwn(int a, int b, int p) 75 { 76 // 添加 company 控制A owning p% of company B 77 for (int i = 1; i < MaxN; ++i) 78 { 79 if (controlling[i][a]) 80 { 81 own[i][b] += p; 82 } 83 } 84 for (int i = 1; i < MaxN; ++i) 85 { 86 if (own[i][b] > 50) 87 { 88 addControl(i, b); 89 } 90 } 91 } 92 93 int main() 94 { 95 #ifdef HOME 96 freopen("in", "r", stdin); 97 //freopen("out", "w", stdout); 98 #endif 99 100 freopen("concom.in", "r", stdin); 101 freopen("concom.out", "w", stdout); 102 103 memset(controlling, false, sizeof(controlling)); 104 105 // Company A = Company B 106 for (int i = 0; i < MaxN; ++i) 107 { 108 controlling[i][i] = true; 109 } 110 cin >> N; 111 int a, b, p; 112 for (int i = 0; i < N; ++i) 113 { 114 cin >> a >> b >> p; 115 addOwn(a, b, p); 116 } 117 118 for (int i = 1; i < MaxN; ++i) 119 { 120 for (int j = 1; j < MaxN; ++j) 121 { 122 if ((i != j) && controlling[i][j]) 123 { 124 cout << i << " " << j << endl; 125 } 126 } 127 } 128 129 #ifdef HOME 130 std::cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; 131 #endif 132 return 0; 133 }