您的位置:首页 > 其它

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即为答案。
*/

/*
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: