DP
苦手。とりあえず、典型問題を解いて慣れていきたい。
ということで、練習問題。
- C.Welcome to Code Jam
文字列が与えられ、そのなかで「welcome to code jam」という文字がいくつ作れるか。
解説が載ってたので、そのとおりにやってみた。
(文字列の長さ)x(19パターン)の配列を用意しておいて、そこに入れていく。19パターンは「w」「we」「wel」...「welcome to code jam」。配列は、文字列のi番目までにそれぞれのパターンがいくつあるか。例えば、i番目の文字が"l"ならば、(i-1番目での「wel」の個数)+(i-1番目での「we」の個数)を(i番目の「wel」の個数)にする。違う文字なら(i-1番目の「wel」の個数)を(i番目の「wel」の個数)にする。
#include <iostream> using namespace std; int dp[500][19]; string pat = "welcome to code jam"; void show(int num){ num=num%10000; cout << num/1000; num=num%1000; cout << num/100; num=num%100; cout << num/10; num=num%10; cout << num << endl; } void calc(string str){ for(int i=0; i<500; i++) for(int j=0; j<19; j++) dp[i][j] = 0; for(int i=0; i<str.length(); i++) for(int j=0; j<19; j++){ if(i>=1) dp[i][j] = dp[i-1][j]; if(str[i]==pat[j]){ if(j==0) dp[i][j]++; if(i-1>=0 && j-1>=0) dp[i][j] = (dp[i][j] + dp[i-1][j-1])%10000; } } /* for(int j=0; j<19; j++){ for(int i=0; i<str.length(); i++){ cout << dp[i][j]; } cout << endl; } */ show(dp[str.length()-1][18]); } int main(){ string str; int n; cin >> n; cin.get(); for(int i=0; i<n; i++){ getline(cin, str); cout << "Case #" << i+1 << ": "; calc(str); } return 0; }