(ΦωΦ)<これの答えですよー。目次はここ。
---
問4-1
(ΦωΦ)<再帰
#include <iostream>
#include <algorithm>
using namespace std;
string s, t;
int n, m;
vector<vector<int>> dp;
// sのi文字分を見た(次にs[i]を見る)
// tのj文字分を見た(次にt[j]を見る)
// そこからの最大数を返す
int rec(int i, int j) {
int &res = dp[i][j];
if(res != -1) { return res; }
// 全部見たので、ここからの最大数は0
if(i==n && j==m) { return res = 0; }
// sは全部見たので、tを1文字進める
else if(i==n) {
res = max(res, rec(i, j+1));
// tは全部見たので、sを1文字進める
} else if(j==m) {
res = max(res, rec(i+1, j));
} else {
// 同じ文字だったので1を加える。sもtも1文字進める
if(s[i] == t[j]) {
res = max(res, rec(i+1, j+1) + 1);
} else {
// sだけ1文字進める
res = max(res, rec(i+1, j));
// tだけ1文字進める
res = max(res, rec(i, j+1));
}
}
return res;
}
int main(void) {
int q; scanf("%d", &q);
for(int cases=0; cases<q; cases++) {
cin >> s >> t;
n = s.size(), m = t.size();
dp.assign(n+1, vector<int>(m+1, -1));
int res = rec(0, 0);
printf("%d\n", res);
}
return 0;
}
(ΦωΦ)<forループ その1
#include <iostream>
#include <algorithm>
using namespace std;
vector<vector<int>> dp;
int main(void) {
int q; scanf("%d", &q);
string s, t;
int n, m;
for(int cases=0; cases<q; cases++) {
cin >> s >> t;
n = s.size(), m = t.size();
dp.assign(n+1, vector<int>(m+1));
for(int i=0; i<=n; i++) {
for(int j=0; j<=m; j++) {
if(i==n && j==m) { continue; }
if(i==n) { dp[i][j+1] = max(dp[i][j+1], dp[i][j]); }
else if(j==m) { dp[i+1][j] = max(dp[i+1][j], dp[i][j]); }
else {
if(s[i] == t[j]) {
dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j] + 1);
} else {
dp[i][j+1] = max(dp[i][j+1], dp[i][j]);
dp[i+1][j] = max(dp[i+1][j], dp[i][j]);
}
}
}
}
int res = dp[n][m];
printf("%d\n", res);
}
return 0;
}
(ΦωΦ)<forループ その2 渡すのではなく貰うようにする
#include <iostream>
#include <algorithm>
using namespace std;
vector<vector<int>> dp;
int main(void) {
int q; scanf("%d", &q);
string s, t;
int n, m;
for(int cases=0; cases<q; cases++) {
cin >> s >> t;
n = s.size(), m = t.size();
dp.assign(n+1, vector<int>(m+1));
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
if(i==0 && j==0) { continue; }
if(i==0) { dp[i][j] = max(dp[i][j], dp[i][j-1]); }
else if(j==0) { dp[i][j] = max(dp[i][j], dp[i-1][j]); }
else {
if(s[i-1] == t[j-1]) {
dp[i][j] = max(dp[i][j], dp[i-1][j-1] + 1);
} else {
dp[i][j] = max(dp[i][j-1], dp[i-1][j]);
}
}
}
}
int res = dp[n][m];
printf("%d\n", res);
}
return 0;
}
(ΦωΦ)<forループ その3 端のチェックは要らない
#include <iostream>
#include <algorithm>
using namespace std;
vector<vector<int>> dp;
int main(void) {
int q; scanf("%d", &q);
string s, t;
int n, m;
for(int cases=0; cases<q; cases++) {
cin >> s >> t;
n = s.size(), m = t.size();
dp.assign(n+1, vector<int>(m+1));
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
if(s[i-1] == t[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
} else {
dp[i][j] = max(dp[i][j-1], dp[i-1][j]);
}
}
}
int res = dp[n][m];
printf("%d\n", res);
}
return 0;
}
(ΦωΦ)<forループ その4 ループカウンタを1ずらす
#include <iostream>
#include <algorithm>
using namespace std;
vector<vector<int>> dp;
int main(void) {
int q; scanf("%d", &q);
string s, t;
int n, m;
for(int cases=0; cases<q; cases++) {
cin >> s >> t;
n = s.size(), m = t.size();
dp.assign(n+1, vector<int>(m+1));
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(s[i] == t[j]) {
dp[i+1][j+1] = dp[i][j] + 1;
} else {
dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]);
}
}
}
int res = dp[n][m];
printf("%d\n", res);
}
return 0;
}
(ΦωΦ)<おしまい