数理的考察に基づくアルゴリズム設計について議論する。以下に代表的な問題パターンとその解法を示す。
「CF1183F Topforces Strikes Back」
最大値選択問題の最適化戦略を検討する。以下の条件を満たす組み合わせを探索する:
- 単一要素:最大値を選択
- 二要素:最大値の因数である必要がある
- 三要素:最大値とその約数の組み合わせ
証明概要
- 最大値以外の要素を含む場合、最大値への置換が最適
- 二要素の和は最大値単独より小さくなる
- 三要素の場合は約数の線形結合を評価
実装コード
#include <bits/stdc++.h>
using namespace std;
int main() {
int T; cin >> T;
vector<long long> dp(100001);
for(int k=2; k<=T+1; k++) {
int Q, M; scanf("%d%d", &Q, &M);
dp[1] = 1;
for(int i=2; i<=M; i++) {
int prev = i - (i-1)/k - 1;
int pos = prev - dp[prev] + 1;
dp[i] = pos + (pos-1)/(k-1) + 1;
}
while(Q--) {
int n; scanf("%d", &n);
printf("%lld ", dp[n]);
}
cout << endl;
}
}
「Stoi2031 フレームワーク」
再帰構造を持つ問題の解法パターン。部分問題の解を再利用する戦略を示す。
解法概要
- 操作後の残り要素数をlとおく
- 子問題ans_lの解を現在の問題に適用
- 反転操作を考慮した位置計算
- 削除された要素数を補正
実装コード
#include <bits/stdc++.h>
using namespace std;
int main() {
int T; cin >> T;
vector<int> memo(100001);
for(int k=2; k<=T+1; k++) {
int Q, M; scanf("%d%d", &Q, &M);
memo[1] = 1;
for(int i=2; i<=M; i++) {
int last = i - (i-1)/k - 1;
int index = last - memo[last] + 1;
memo[i] = index + (index-1)/(k-1) + 1;
}
while(Q--) {
int n; scanf("%d", &n);
printf("%d ", memo[n]);
}
cout << endl;
}
}
「HNOI2011 カーノン問題」
集合選択の制約条件を満たす場合の数え上げ問題。以下が重要な性質:
DPによる解法
- 無順序集合の条件を順序付き問題に変換
- 組み合わせ数A(n,m)の計算
- 重複要素を排除した遷移式
数学的証明
- 任意のi-1要素を選ぶ場合、最終要素は一意に決まる
- 空集合を含む場合の補正
- 要素の重複を排除する補正項
実装コード
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e8+7;
long long power(long long base, long long exp) {
long long res = 1;
while(exp) {
if(exp & 1) res = res * base % MOD;
base = base * base % MOD;
exp >>= 1;
}
return res;
}
int main() {
long long N, M;
cin >> N >> M;
long long total = power(2, N) - 1;
vector<long long> A(M+2), fact(M+2);
A[0] = 1, fact[0] = 1;
for(int i=1; i<=M; i++) {
A[i] = A[i-1] * (total - i + 1) % MOD;
fact[i] = fact[i-1] * i % MOD;
}
vector<long long> dp(M+2);
for(int i=3; i<=M; i++) {
dp[i] = (A[i-1] - dp[i-1] + MOD) % MOD;
dp[i] = (dp[i] - dp[i-2] * (i-1) % MOD * (total - i + 2) % MOD + MOD) % MOD;
}
cout << dp[M] * power(fact[M], MOD-2) % MOD << endl;
}