USACO 之 Section 2.3 (已解决)
2016-04-19 21:52
309 查看
Longest Prefix:
/*
dp:
dp[i] := 第i个位置是否继续可放集合里面的某一个元素(数组从0开始编号)
dp[i + len(集合里面的元素)] = true
初始化:dp[0] = true
答案:dp数组从S.size()位置开始,向前遍历,如果dp[i] = true,i即为答案。
*/
dp[i][j] := 在层数小于等于i,节点数恰为j的情况下,家谱树的个数。
dp[i][j] = ∑(dp[i-1]
* dp[i-1][j-1-n])
即:∑(左子树*右子树)
初始化:dp[i][0] = 1
答案:
ans := 层数恰为K,节点数恰为N的情况下,家谱树的个数。
ans = dp[K]
- dp[K-1]
*/
Zero Sum:
/*
搜索即可
*/
Money Systems:
/*
完全背包变形:(每个硬币都有无限个可用)
dp[i][j] := 前i种硬币,恰构造出j的方案数
dp[i][j] = dp[i-1][j] + dp[i][j-coin[i]]
*/
Controlling Companies:
解法一:
/*
模拟控制公司的三个条件,逐渐更新公司之间控制的状态。
*/
[b]解法二(官方答案方法):
/*
两个步骤:
(1)添加 company A owning p% of company B
(2)添加 company A controls company B
*/
/*
dp:
dp[i] := 第i个位置是否继续可放集合里面的某一个元素(数组从0开始编号)
dp[i + len(集合里面的元素)] = true
初始化:dp[0] = true
答案:dp数组从S.size()位置开始,向前遍历,如果dp[i] = true,i即为答案。
*/
/* ID: Jming PROG: prefix LANG: C++ */ #include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <string> #include <locale> #include <cmath> #include <vector> #include <cstring> #include <map> #include <utility> #include <queue> #include <stack> #include <set> #include <bitset> #include <functional> #include <cassert> using namespace std; typedef pair<int, int> PII; typedef long long int64; const int INF = 0x3f3f3f3f; const int modPrime = 3046721; const double eps = 1e-9; const int MaxN = 200010; const int MaxM = 20; bool dp[MaxN]; vector<string> vecStr; string S; void Solve() { fill(dp, dp + MaxN, false); dp[0] = true; for (int i = 0; i < S.size(); ++i) { if (dp[i]) { for (int j = 0; j < vecStr.size(); ++j) { int k = 0; for (; k < vecStr[j].size(); ++k) { if (S[k + i] != vecStr[j][k]) { break; } } if (vecStr[j].size() == k) { dp[i + vecStr[j].size()] = true; int a = 0; } } } } for (int i = S.size(); i >= 0; --i) { if (dp[i]) { cout << i << endl; return; } } } int main() { #ifdef HOME freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif freopen("prefix.in", "r", stdin); freopen("prefix.out", "w", stdout); string inStr; while ((cin >> inStr) && ("." != inStr)) { vecStr.push_back(inStr); } while (cin >> inStr) { S += inStr; } Solve(); #ifdef HOME cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl; #endif return 0; }
Cow Pedigrees:
/*dp[i][j] := 在层数小于等于i,节点数恰为j的情况下,家谱树的个数。
dp[i][j] = ∑(dp[i-1]
* dp[i-1][j-1-n])
即:∑(左子树*右子树)
初始化:dp[i][0] = 1
答案:
ans := 层数恰为K,节点数恰为N的情况下,家谱树的个数。
ans = dp[K]
- dp[K-1]
*/
/* ID: Jming PROG: nocows LANG: C++ */ #include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <string> #include <locale> #include <cmath> #include <vector> #include <cstring> #include <map> #include <utility> #include <queue> #include <stack> #include <set> #include <bitset> #include <functional> #include <cassert> using namespace std; typedef pair<int, int> PII; typedef long long int64; const int INF = 0x3f3f3f3f; const int modPrime = 3046721; const double eps = 1e-9; const int MaxN = 210; const int MaxK = 110; const int Mod = 9901; int N, K; int dp[MaxK][MaxN]; void Solve() { for (int i = 0; i <= K; ++i) { dp[i][0] = 1; } for (int i = 1; i <= K; ++i) { for (int j = 1; j <= N; j += 2) { for (int n = 0; n <= (j - 1); ++n) { dp[i][j] = (dp[i][j] + dp[i - 1] * dp[i - 1][j - 1 - n]) % Mod; //cout << i << "层" << j << "个节点" << " ---> " << dp[i][j] << endl; } } } // 由于dp[K] 取余之后,可能小于dp[K-1] ,所以先加Mod再取余。 cout << (dp[K] - dp[K - 1] + Mod)%Mod << endl; } int main() { #ifdef HOME freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif freopen("nocows.in", "r", stdin); freopen("nocows.out", "w", stdout); cin >> N >> K; Solve(); #ifdef HOME cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; #endif return 0; }
Zero Sum:
/*
搜索即可
*/
/* ID: Jming PROG: zerosum LANG: C++ */ #include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <string> #include <locale> #include <cmath> #include <vector> #include <cstring> #include <map> #include <utility> #include <queue> #include <stack> #include <set> #include <bitset> #include <functional> #include <cassert> using namespace std; typedef pair<int, int> PII; typedef long long int64; const int INF = 0x3f3f3f3f; const int modPrime = 3046721; const double eps = 1e-9; const int MaxN = 210; const int MaxK = 110; const int Mod = 9901; const char symbol[] = { '+', '-', ' ' }; int N; char arr[20]; int arrLen; vector<string> ans; bool ZeroSum(string str) { str = "0+" + str; int sum = str[0] - '0'; int num = 0; for (size_t i = 2; i < str.size(); i += 2) { num = str[i] - '0'; char syb = str[i - 1]; while ((i + 1 < str.size()) && (' ' == str[i + 1])) { num = num * 10 + (str[i + 2] - '0'); i += 2; } switch (syb) { case '+': { sum += num; break; } case '-': { sum -= num; break; } default: break; } } return (0 == sum); } void Dfs(int pos) { if (pos == arrLen) { if (ZeroSum(arr)) { ans.push_back(arr); } return; } for (size_t j = 0; j < strlen(symbol); ++j) { arr[pos] = symbol[j]; Dfs(pos + 2); } } void Solve() { arrLen = ((N << 1) - 1); int num = 1; for (size_t i = 0; i < arrLen; i += 2) { arr[i] = ('0' + num); ++num; } Dfs(1); sort(ans.begin(), ans.end()); for (size_t i = 0; i < ans.size(); ++i) { cout << ans[i] << endl; } } int main() { #ifdef HOME freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif freopen("zerosum.in", "r", stdin); freopen("zerosum.out", "w", stdout); cin >> N; Solve(); #ifdef HOME std::cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; #endif return 0; }
Money Systems:
/*
完全背包变形:(每个硬币都有无限个可用)
dp[i][j] := 前i种硬币,恰构造出j的方案数
dp[i][j] = dp[i-1][j] + dp[i][j-coin[i]]
*/
/* ID: Jming PROG: money LANG: C++ */ #include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <string> #include <locale> #include <cmath> #include <vector> #include <cstring> #include <map> #include <utility> #include <queue> #include <stack> #include <set> #include <bitset> #include <functional> #include <cassert> using namespace std; typedef pair<int, int> PII; typedef long long int64; const int INF = 0x3f3f3f3f; const int modPrime = 3046721; const double eps = 1e-9; const int MaxN = 10010; const int MaxM = 110; int V, N; vector<int> availableCoins; long long dp[MaxN]; void Solve() { dp[0] = 1; for (int i = 0; i < V; ++i) { for (int j = availableCoins[i]; j <= N; ++j) { dp[j] = dp[j] + dp[j - availableCoins[i]]; } /* // 01背包写法 for (int j = N; j >= availableCoins[i]; --j) { for (int k = 1; k <= (j / availableCoins[i]); ++k) { dp[j] = dp[j] + dp[j - k*availableCoins[i]]; } } */ } cout << dp << endl; } int main() { #ifdef HOME freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif freopen("money.in", "r", stdin); freopen("money.out", "w", stdout); cin >> V >> N; int coin; for (int i = 0; i < V; ++i) { cin >> coin; availableCoins.push_back(coin); } Solve(); #ifdef HOME std::cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; #endif return 0; }
Controlling Companies:
解法一:
/*
模拟控制公司的三个条件,逐渐更新公司之间控制的状态。
*/
/* ID: Jming PROG: concom LANG: C++ */ #include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <string> #include <locale> #include <cmath> #include <vector> #include <cstring> #include <map> #include <utility> #include <queue> #include <stack> #include <set> #include <bitset> #include <functional> #include <cassert> using namespace std; typedef pair<int, int> PII; typedef long long int64; const int INF = 0x3f3f3f3f; const int modPrime = 3046721; const double eps = 1e-9; const int MaxN = 110; const int MaxM = 110; int N; bool controlling[MaxN][MaxN]; int stock[MaxN][MaxN]; void Solve() { bool updated = true; while (updated) { updated = false; /* Company A controls K(K >= 1) companies denoted C1, ..., CK with each company Ci owning xi% of company B and x1 + .... + xK > 50%. */ for (int i = 1; i < MaxN; ++i) { for (int j = 1; j < MaxN; ++j) { if (!controlling[i][j]) { int sum = 0; for (int k = 1; k < MaxN; ++k) { if (controlling[i][k]) { sum += stock[k][j]; } } if (sum > 50) { controlling[i][j] = true; if (!updated) { updated = true; } } } } } } for (int i = 1; i < MaxN; ++i) { for (int j = 1; j < MaxN; ++j) { if ((i != j) && controlling[i][j]) { cout << i << " " << j << endl; } } } } int main() { #ifdef HOME freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif freopen("concom.in", "r", stdin); freopen("concom.out", "w", stdout); memset(controlling, false, sizeof(controlling)); // Company A = Company B for (int i = 0; i < MaxN; ++i) { controlling[i][i] = true; } cin >> N; int a, b; for (int i = 0; i < N; ++i) { cin >> a >> b; cin >> stock[a]; // Company A owns more than 50 % of Company B if (stock[a][b] > 50) { controlling[a][b] = true; } } Solve(); #ifdef HOME std::cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; #endif return 0; }
[b]解法二(官方答案方法):
/*
两个步骤:
(1)添加 company A owning p% of company B
(2)添加 company A controls company B
*/
/* ID: Jming PROG: concom LANG: C++ */ #include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cstddef> #include <iterator> #include <algorithm> #include <string> #include <locale> #include <cmath> #include <vector> #include <cstring> #include <map> #include <utility> #include <queue> #include <stack> #include <set> #include <bitset> #include <functional> #include <cassert> using namespace std; typedef pair<int, int> PII; typedef long long int64; const int INF = 0x3f3f3f3f; const int modPrime = 3046721; const double eps = 1e-9; const int MaxN = 110; const int MaxM = 110; int N; bool controlling[MaxN][MaxN]; int own[MaxN][MaxN]; // 添加 company A controls company B void addControl(int a, int b) { if (controlling[a][b]) { return; } controlling[a][b] = true; for (int i = 0; i < MaxN; ++i) { own[a][i] += own[b][i]; } // 控制A的公司,也可以控制公司B了 for (int i = 1; i < MaxN; ++i) { if (controlling[i][a]) { addControl(i, b); } } // A控制更多的公司 for (int i = 1; i < MaxN; ++i) { if (own[a][i] > 50) { addControl(a, i); } } } // 添加 company A owning p% of company B void addOwn(int a, int b, int p) { // 添加 company 控制A owning p% of company B for (int i = 1; i < MaxN; ++i) { if (controlling[i][a]) { own[i][b] += p; } } for (int i = 1; i < MaxN; ++i) { if (own[i][b] > 50) { addControl(i, b); } } } int main() { #ifdef HOME freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif freopen("concom.in", "r", stdin); freopen("concom.out", "w", stdout); memset(controlling, false, sizeof(controlling)); // Company A = Company B for (int i = 0; i < MaxN; ++i) { controlling[i][i] = true; } cin >> N; int a, b, p; for (int i = 0; i < N; ++i) { cin >> a >> b >> p; addOwn(a, b, p); } for (int i = 1; i < MaxN; ++i) { for (int j = 1; j < MaxN; ++j) { if ((i != j) && controlling[i][j]) { cout << i << " " << j << endl; } } } #ifdef HOME std::cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << "s" << endl; #endif return 0; }
相关文章推荐
- 有关字符串编程
- 33.JAVA编程思想——JAVA IO File类
- Iwfu-保存Fragment切换时的UI状态/保存销毁Activity后再次进入的视图状态
- 32.JAVA编程思想——JAVA IO添加属性和接口
- leetcode——89——Gray Code
- Java 序列化Serializable详解
- strstr代码
- 菜鸟入门_Python_机器学习(1)_线性可分的双月实验
- A strange lift
- 站立会议第一天
- bzoj4537: [Hnoi2016]最小公倍数
- 这次栽倒在sscanf函数上------ 看看错误的语句:int nRet = sscanf("xxx=yyy", "%s=%s", szKey, szValue);
- 31.JAVA编程思想——JAVA IO系统输入和输出
- curl 命令常用
- 异常
- 30.JAVA编程思想——违例匹配
- 静态链表
- 2-SAT学习笔记
- 16.4.19 杭州某创业公司前端开发实习生面试分享(大神勿入)
- FZU 2151 OOXX Game