Once Petya and Vasya invented a new game and called it "Smart Boy". They located a certain set of words — the dictionary — for the game. It is admissible for the dictionary to contain similar words.
The rules of the game are as follows: first the first player chooses any letter (a word as long as 1) from any word from the dictionary and writes it down on a piece of paper. The second player adds some other letter to this one's initial or final position, thus making a word as long as 2, then it's the first player's turn again, he adds a letter in the beginning or in the end thus making a word as long as 3 and so on. But the player mustn't break one condition: the newly created word must be a substring of a word from a dictionary. The player who can't add a letter to the current word without breaking the condition loses.
Also if by the end of a turn a certain string s is written on paper, then the player, whose turn it just has been, gets a number of points according to the formula:
where
is a sequence number of symbol c in Latin alphabet, numbered starting from 1. For example, , and . is the number of words from the dictionary where the line s occurs as a substring at least once.Your task is to learn who will win the game and what the final score will be. Every player plays optimally and most of all tries to win, then — to maximize the number of his points, then — to minimize the number of the points of the opponent.
InputThe first input line contains an integer n which is the number of words in the located dictionary (1 ≤ n ≤ 30). The n lines contain the words from the dictionary — one word is written on one line. Those lines are nonempty, consisting of Latin lower-case characters no longer than 30 characters. Equal words can be in the list of words.
OutputOn the first output line print a line "First" or "Second" which means who will win the game. On the second line output the number of points of the first player and the number of points of the second player after the game ends. Separate the numbers by a single space.
Examples input Copy 2 aba abac output Second 29 35 input Copy 3 artem nik max output First 2403 1882
题意:有n个只由小写字母组成的字符串,两个人轮流从一个空字符串开始构造字符串,要求每个人在其操作轮要加一个字符在已有字符串前面或者后面使得这个字符串依旧是这n个字符串中某些字符串的子串,如果没有合法方案则该人失败,否则该人得分,假设该人操作后字符串为s,则本轮得分Score(s)=(∑i=1|s|value(si))∗max1≤i≤|s|{|value(si)}+num(s),其中value(c)为c在26个字母中的位置,即value(′a′)=1,value(′z′)=26,num(s)为这n个字符串中以s为子串的字符串数量,每个人在操作时采取最优策略让自己赢,且在保证自己赢的情况下使得自己得分最高,在保证自己赢且得分最高的情况下使得对方得分尽可能少,问最后哪一个人赢以及两个人的得分
解题思路:由于字符串数量和长度都不超过30,不同子串数不多,预处理出每个子串的和num,之后对所有可能的情况记忆化搜索即可 #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <map> #include <set> #include <stack> #include <queue> #include <vector> #include <bitset> #include <functional> using namespace std; #define LL long long const int INF = 0x3f3f3f3f; struct node { int sg, sum1, sum2; bool operator < (const node &x)const { if (sg != x.sg) return sg < x.sg; if (sum1 != x.sum1) return sum1 < x.sum1; return sum2 > x.sum2; } }; set<string>S; map<string, node>mp; map<string, int>num; int get(string s) { int ans = 0, mx = 0, len = s.length(); for (int i = 0; i < len; i++) { ans += s[i] - 'a' + 1; mx = max(mx, s[i] - 'a' + 1); } return ans * mx + num[s]; } node dfs(string s) { if (mp.find(s) != mp.end()) return mp[s]; node ans = { 0, 0, 0 }; for (int i = 0; i < 26; i++) { string ss = s + char('a' + i); if (S.find(ss) != S.end()) { node tmp = dfs(ss); swap(tmp.sum1, tmp.sum2); tmp.sg ^= 1; tmp.sum1 += get(ss); if (ans < tmp) ans = tmp; } ss = char('a' + i) + s; if (S.find(ss) != S.end()) { node tmp = dfs(ss); swap(tmp.sum1, tmp.sum2); tmp.sg ^= 1; tmp.sum1 += get(ss); if (ans < tmp) ans = tmp; } } return mp[s] = ans; } int main() { int n, len; string s, ss; while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) { cin >> s; set<string>tmp; len = s.length(); for (int j = 0; j < len; j++) { for (int k = j; k < len; k++) { ss = s.substr(j, k - j + 1); S.insert(ss); if (tmp.find(ss) == tmp.end()) { tmp.insert(ss); num[ss]++; } } } } node ans = dfs(""); if (ans.sg) printf("First\n"); else printf("Second\n"); printf("%d %d\n", ans.sum1, ans.sum2); } return 0; }