SRM329 D2H ProbabilisticTranslator

TopCoder Statistics - Problem Statement

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2010, TopCoder, Inc. All rights reserved.

単語列とそれぞれの単語をある単語に変換できる辞書と二つの単語が並んだ時に得られる点が与えられた時に,得点の最大化をする.

$$ dp[i][j] := i番目の単語を辞書からj番目に変換した時の最大値 $$

として動的計画法.$dp[i][j]$から$i+1$番目に遷移するときに,$i$番目の単語を$j$番目に変換した文字列と,$i+1$番目の単語を$k$番目に変換した文字列のペアで得点が得られる場合は加算する.先に$dp$の添字に対応する文字列のテーブルを作ってしまった方が楽だと思った.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define INF 1<<30
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

vector<string> split(const string &str, char delim) {
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos) {
      res.push_back(string(str, current, found - current));
      current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

int dp[2505][55]; //i番目にその語の辞書からj番目に変換するときの最大値

class ProbabilisticTranslator {
  public:
  int maximumFidelity(vector <string> text, vector <string> dictionary, vector <string> frequencies) {
      vector<string> v;
      rep(i, text.size()) {
          vector<string> ret = split(text[i], ' ');
          rep(j, ret.size()) {
              v.push_back(ret[j]);
          }
      }
      
      map<string, vector<string> > m;
      rep(i, dictionary.size()) {
          vector<string> t = split(dictionary[i], ' ');

          REP(j, 2, t.size()) {
              m[t[0]].push_back(t[j]);
          }
      }

      map<pair<string, string>, int> fre;
      rep(i, frequencies.size()) {
          vector<string> t = split(frequencies[i], ' ');
          stringstream ss;
          ss << t[2];
          ss >> fre[mp(t[0], t[1])];
      }

      vector<vector<string> > table;
      rep(j, v.size()) {
          table.push_back(m[v[j]]);
      }

      memset(dp, 0, sizeof(dp));
      rep(i, v.size()-1) {
          rep(j, table[i].size()) {
              string s = table[i][j];
              rep(k, table[i+1].size()) {
                  string t = table[i+1][k];
                  if(fre.count(mp(s, t))) {
                      dp[i+1][k] = max(dp[i+1][k], dp[i][j] + fre[mp(s, t)]);
                  } else {
                      dp[i+1][k] = max(dp[i+1][k], dp[i][j]);
                  }
              }
          }
      }

      int ans = 0;
      rep(j, 2505) {
          rep(k, 55) {
              ans = max(ans, dp[j][k]);
          }
      }

      return ans;
  }
};
Dec 1st, 2016