解决 Google Code Jam 2009 中的"Welcome to Code Jam"
Solving "Welcome to Code Jam" from Google Code Jam 2009
我正在尝试解决以下代码堵塞问题,我取得了一些进展,但在少数情况下,我的代码给出了错误的输出。欢迎来到代码开发大赛
所以我偶然发现了来自俄罗斯的开发"rem"的解决方案。我不知道他/她的解决方案如何正常工作..代码...
const string target = "welcome to code jam";
char buf[1<<20];
int main() {
freopen("input.txt", "rt", stdin);
freopen("output.txt", "wt", stdout);
gets(buf);
FOR(test, 1, atoi(buf)) {
gets(buf);
string s(buf);
int n = size(s);
int k = size(target);
vector<vector<int> > dp(n+1, vector<int>(k+1));
dp[0][0] = 1;
const int mod = 10000;
assert(k == 19);
REP(i, n) REP(j, k+1) {// Whats happening here
dp[i+1][j] = (dp[i+1][j]+dp[i][j])%mod;
if (j < k && s[i] == target[j])
dp[i+1][j+1] = (dp[i+1][j+1]+dp[i][j])%mod;
}
printf("Case #%d: %04dn", test, dp[n][k]);
}
exit(0);
}//credit rem
有人可以解释一下两个循环中发生了什么吗?
谢谢。
他在做什么:动态编程,到目前为止你也可以看到。
他有2D数组,你需要了解它的语义是什么。事实是,dp[i][j]
计算他可以使用输入字符串中的所有字母获取welcome to code jam
前 j
个字母的子序列的方法数量,直到第 i 个索引。两个索引都是从 1 开始的,以允许不从字符串中获取任何字母的情况。
例如,如果输入为:
welcome to code jjam
在不同情况下,dp
的值将是:
dp[1][1] = 1; // first letter is w. perfect just the goal
dp[1][2] = 0; // no way to have two letters in just one-letter string
dp[2][2] = 1; // again: perfect
dp[1][2] = 1; // here we ignore the e. We just need the w.
dp[7][2] = 2; // two ways to construct we: [we]lcome and [w]elcom[e].
您专门询问的循环根据已计算的动态值计算新的动态值。
几天前我在练习这个问题,偶然发现了这个问题。
我怀疑说"他在做动态编程"不会解释太多,如果你没有学习DP。
我可以给出更清晰的实现和更简单的解释:
string phrase = "welcome to code jam"; // S
string text; getline(cin, text); // T
vector<int> ob(text.size(), 1);
int ans = 0;
for (int p = 0; p < phrase.size(); ++p) {
ans = 0;
for (int i = 0; i < text.size(); ++i) {
if (text[i] == phrase[p]) ans = (ans + ob[i]) % 10000;
ob[i] = ans;
}
}
cout << setfill('0') << setw(4) << ans << endl;
为了解决这个问题,如果 S 只有一个字符S[0]
我们可以计算它的出现次数。
如果它只有两个字符S[0..1]
我们看到每次出现T[i]==S[1]
索引 i
之前S[0]
出现的次数来增加答案。
对于三个字符S[0..2]
每次出现T[i]==S[2]
同样会按索引i
之前出现的S[0..1]
次数来增加答案。此数字与上一段处理T[i]
时的答案值相同。
如果有四个字符,则答案将是在每个索引找到第四个字符之前增加前三个字符的出现次数,依此类推。
由于每隔一步都使用前一步的值,因此可以逐步解决。在每一步p
我们需要知道在任何索引i
之前S[0..p-1]
子字符串的出现次数,这些子字符串可以保存在与 T 长度相同的整数数组ob
中。然后,每当我们在i
遇到S[p]
时,答案就会上升ob[i]
。为了ob
下一步做好准备,我们还将每个ob[i]
更新为S[0..p]
的出现次数,即当前答案值。
到最后,最新的答案值(以及ob
的最后一个元素(包含整T
中整S
的出现次数,这就是最终答案。
请注意,它以填充 ob
开头。第一步与其他步骤不同;但是计算S[0]
的出现次数意味着每次出现的答案增加1
,这是所有其他步骤所做的,只是它们增加了ob[i]
。因此,当每个ob[i]
最初都1
时,第一步将像所有其他步骤一样运行,使用相同的代码。
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- Visual Studio Code - C++ Debugger 無法啟動
- Visual Studio Code "undefined reference to `WinMain@16'"
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 修改 VS Code 中的默认C++代码段
- 如何配置Visual Studio Code以使用cygwin,cmake和gcc进行调试
- std::to_string - 'to_string' 不是 'std' 的成员 - Visual Studio Code 1.42.0
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- C++新手,想知道如何使用VS code 2019播放音频文件
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- 如何在Visual Studio Code中重命名我的a.exe文件?
- C++ Visual Studio Code 的设置不起作用
- 以某种方式告诉编译器"Do not process line of code"
- 在VS Code中编译C / C ++时如何禁用自动创建EXE文件?
- 将Qt与Visual Studio Code(Windows)一起使用
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- 将Visual Studio Code路径设置为.clang_format文件
- 解决 Google Code Jam 2009 中的"Welcome to Code Jam"
- 在Google Code jam上问的一个c++句子的倒序