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 }

 

posted @ 2016-04-19 21:52  JmingS  阅读(199)  评论(0编辑  收藏  举报