Problem:
Problem J:
Billion Million Thousand
A linguist, Nodvic Natharus Damenhof (commonly called
Dr. Usoperant
), invented an artificial language
Usoperant
in 2007. The word
usoperant
means ‘one which tires’. Damenhof’s goal was to create a complex and
pedantic language that would remind many difficulties in universal communications. Talking in Usoperant, you
should remember the importance of choosing your words in many conversations.
For example of the complexity, you may be confused by the way to say large numbers. Usoperant has some
words that indicate exponential numbers in decimal, described as 10
p
where
p
is a positive integer. In terms of
English, those words might include thousand for 10
3
(1,000), million for 10
6
(1,000,000), and
undecillion
for
10
36
(1,000,000,000,000,000,000,000,000,000,000,000,000).
You can concatinate those words to express larger numbers. When two words
w
1
and
w
2
mean numbers 10
p
1
and 10
p
2
respectively, a concatinated word
w
1
w
2
means 10
p
1
+
p
2
. Using the above examples in English (actually
the following examples are incorrect in English), you can say 10
9
by
millionthousand
, 10
12
by
millionmillion
and 10
39
by
undecillionthousand
. Note that there can be multiple different expressions for a certain number.
For example, 10
9
can also be expressed by
thousandthousandthousand
. It is also possible to insert separators
between the adjacent components like
million-thousand
and
thousand-thousand-thousand
.
In this problem, you are given a few of such words, their representing digits and an expression of a certain number
in Usoperant. Your task is to write a program to calculate the length of the shortest expression which represents
the same number as the given expression.
The expressions in the input do not contain any separators like
millionthousand
. In case of ambiguity, the
expressions should be interpreted as the largest number among possibles. The resultant expressions should
always contain separators like
million-thousand
, so we can distinguish, for example,
x
-
x
(a concatinated word of
two
x
's) and
xx
(just a single word). The separators should not be counted in the length.
Input
The input consists of multiple test cases. Each test case begins with a line including an integer
N
(1 ≤
N
≤ 100).
The integer
N
indicates the number of words in the dictionary of exponential numbers.
The following
N
lines give the words in the dictionary. Each line contains a word
w
i
and an integer
p
i
(1 ≤
i
≤
N
,
1 ≤
p
i
≤ 10), specifying that the word
w
i
expresses an exponential number 10
p
i
in Usoperant. Each
w
i
consists
of at most 100 alphabetical letters.
Then a line which contains an expression of a number in Usoperant follows. The expression consists of at most
200 alphabetical letters.
The end of the input is indicated by a line which contains only a single 0.
Output
For each test case, print a line which contains the case number and the length of the shortest expression which
represents the same number as the 
...(truncated)

Submitted solutions:

code_snippet: #include <stdio.h>
#include <string.h>

int max(int a,int b)
{
    return a>b ? a : b;
}

int min(int a,int b)
{
    return a<b ? a : b;
}

int main()
{
    int n;
    int i,j,k;
    char w[110][110];
    int p[110];
    char expre[210];
    int len[110];
    int dp[210]; //where dp[i] = the maximum value of expre[0]~expre[i]
    int cases = 0;
    while(scanf("%d",&n) && n!=0)
    {
        cases++;
        for(i=0;i<n;i++)
        {
            scanf("%s%d",w[i],&p[i]);
            len[i] = strlen(w[i]);
        }
        scanf("%s",expre);
        for(i=0;i<210;i++)
        {
            dp[i] = 0;
        }
        for(i=0;i<strlen(expre);i++)
        {
            for(j=0;j<n;j++)
            {
                for(k=0;k<strlen(w[j]);k++)
                {
                    if(expre[i+k]!=w[j][k])
                    {
                        break;
                    }
                    else if(k==len[j]-1)
                    {
                        k++;
                        if(dp[i]!=0 || i==0)
                        {
                            dp[i+k] = max(dp[i+k],dp[i]+p[j]);
                        }
                    }
                }
            }
        }
        //for(i=0;i<=strlen(expre);i++) printf("%d ",dp[i]);
        //printf("_%d_ ",dp[strlen(expre)]);
        int maxl = dp[strlen(expre)];
        int temp[maxl+1];
        memset(temp,0,sizeof(temp));
        for(i=0;i<n;i++)
        {
            for(j=0;j<maxl;j++)
            {
                if(temp[j]!=0 || j==0)
                {
                    for(k=1;j+k*p[i]<=maxl;k++)
                    {
                        if(temp[j+k*p[i]]==0)
                        {
                            temp[j+k*p[i]] = temp[j] + k*len[i];
                        }
                        else
                        {
                            temp[j+k*p[i]] = min(temp[j+k*p[i]],temp[j] + k*len[i]);
                        }
                    }
                }
            }
        }
        printf("Case %d: %d\n",cases,temp[maxl]);


    }
}
accuracy: 1
time_ms: 180
memory_kb: 2968
final_rank: 13

code_snippet: #include <bits/stdc++.h>


using namespace std;
//make -f ../makefile SRC=
/*
2 folds:
1. text => max score
2, text + score => min cost

WA
2
nico 2
video 4
niconicovideo
0
output:
10
*/


//------------------------------------------------------------------------------
bool DEBUG = false;
const int INF = 1000000000;

static char buf1[100+5];
static char buf2[200+5];

const int MAX_N = 100;
static string str[MAX_N];
static int val[MAX_N];

static int S0[2000+5];
static int S1[10000+5]; // from 0,...,N-1, with sum
static int S2[10000+5]; // from 0,...,N-1, with sum
//------------------------------------------------------------------------------
// is s the substring from the right of t ?
bool match_at_end(const string& t, int back, const string& s)
{
    int N1 = back+1;
    int N2 = s.size();
    if (N2 > N1) return false;
    return t.substr(N1-N2, N2) == s;
}

int dp0(int N, int K, const string& t, int back)
{
    if (back < 0) return 0;
    if (S0[back] != -1) return S0[back];

    int& res = S0[back];
    res = 0;
    for (int i=0; i<N; ++i)
        if (match_at_end(t, back, str[i]))
            res = max(res, val[i] + dp0(N, K, t, back-str[i].size()));
    return res;
}

int dp1(int N, int sum)
{
    for (int k=0; k<=sum; ++k) { S1[k] = INF; S2[k] = INF; }
    S1[0] = 0;
    for (int i=0; i<N; ++i)
    {
        for (int k1=0; k1<=sum; ++k1)
        {
            if (S1[k1] == INF) continue;
            int m = 1;
            while (k1 + m*val[i] <= sum)
            {
                S2[k1 + m*val[i]] = min(S2[k1 + m*val[i]], S1[k1] + m*int(str[i].size()));
                m++;
            }        
        }
        for (int k=0; k<=sum; ++k) { S1[k] = min(S1[k], S2[k]); S2[k] = INF; }
        //printf("i=%d:\n",i); for (int n=0; n<=sum; n++) if (S1[n]!=INF) printf("k=%d, S1=%d\n",n,S1[n]); printf("\n");
    }
    int res = S1[sum];
    return res;
}

//------------------------------------------------------------------------------
int solve(int N, const string& t)
{
    //--------------------------------------------------------------------------
    // base cases:
    //--------------------------------------------------------------------------
    // init:
    int K = t.size();
    for (int k=0; k<K; ++k) S0[k] = -1;

    if (DEBUG)
    {
        printf("N=%d, K=%d, t=%s\n", N, K, t.c_str());
        for (int i=0; i<N; ++i) printf("i=%d, str=%s, val=%d\n",i, str[i].c_str(), val[i]);
    }

    //--------------------------------------------------------------------------
    // compute:
    int max_score = dp0(N, K, t, K-1);    
    if (DEBUG) printf("max_score=%d\n", max_score);

    int min_cost = dp1(N, max_score);

    //--------------------------------------------------------------------------
    // report:
    //printf("%d\n", res);

    return min_cost;
}

//------------------------------------------------------------------------------
void test()
{

}

//------------------------------------------------------------------------------
int main()
{
    //test(); return 0;
    //DEBUG = true;
    //--------------------------------------------------------------------------
    int N, num;
    int t = 1;
    while (true)
    {
        num = scanf("%d ", &N);
        if (N == 0) break;
        for (int i=0; i<N; ++i)
        {
            num = scanf("%s %d ", buf1, &val[i]);
            str[i] = string(buf1);
        }
        num = scanf("%s ", buf2);
        printf("Case %d: %d\n", t++, solve(N, string(buf2)));
    }
    //--------------------------------------------------------------------------
    return 0;
}
//------------------------------------------------------------------------------
accuracy: 1
time_ms: 160
memory_kb: 3352
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

const int INF = 10101010;

int main(){
    int cc = 0;
    int n;
    while(cin >>n,n){
        vector<string> s(n);
        vector<int> p(n),l(n);
        rep(i,n){
            cin >>s[i] >>p[i];
            l[i] = s[i].size();
        }

        string t;
        cin >>t;
        int T = t.size();

        vector<int> dp(T+1,-INF);
        dp[0] = 0;
        rep(i,T){
            rep(j,n){
                if(i+l[j] > T) continue;
                if(s[j] == t.substr(i,l[j])){
                    dp[i+l[j]] = max(dp[i+l[j]], dp[i]+p[j]);
                }
            }
        }

        int V = dp[T];
        dp = vector<int>(V+1, INF);
        dp[0] = 0;
        rep(i,V){
            rep(j,n){
                int ni = i+p[j];
                if(ni > V) continue;
                dp[ni] = min(dp[ni], dp[i]+l[j]);
            }
        }

        cout << "Case " << cc+1 << ": " << dp[V] << "\n";
        ++cc;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3200
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

template<typename T1,typename T2> void chmin(T1 &a,T2 b){if(a>b) a=b;};
template<typename T1,typename T2> void chmax(T1 &a,T2 b){if(a<b) a=b;};

signed main(){
  Int n;
  Int cnt=0;
  while(cin>>n,n){
    vector<string> ss(n);
    vector<Int> ls(n),vs(n);
    for(Int i=0;i<n;i++) cin>>ss[i]>>vs[i],ls[i]=ss[i].size();
    string t;
    cin>>t;
    Int m=t.size();

    const Int INF = 1e9;
    vector<Int> dp1(m+1,-INF);
    dp1[0]=0;

    for(Int i=0;i<m;i++){
      for(Int j=0;j<n;j++){
	if(i+ls[j]>m) continue;
	if(t.substr(i,ls[j])!=ss[j]) continue;
	chmax(dp1[i+ls[j]],dp1[i]+vs[j]);
      }
    }

    vector<Int> dp2(dp1[m]+1,INF);
    dp2[0]=0;
    for(Int i=0;i<dp1[m];i++){
      for(Int j=0;j<n;j++){
	if(i+vs[j]>dp1[m]) continue;
	chmin(dp2[i+vs[j]],dp2[i]+ls[j]);
      }      
    }
    
    cout<<"Case "<<++cnt<<": "<<dp2[dp1[m]]<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3156
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
int main(){
    int n,cnt=0;
    while(cin>>n,n){
        vector<string>S(n);
        vector<int>v(n),len(v);
        r(i,n)cin>>S[i]>>v[i],len[i]=S[i].size();

        string t;
        cin>>t;
        int m=t.size();

        vector<int>dp(m+1,-1e9);
        dp[0]=0;

        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(i+len[j]>m)continue;
                if(t.substr(i,len[j])!=S[j])continue;
                dp[i+len[j]] = max(dp[i+len[j]],dp[i]+v[j]);
            }
        }

        vector<int>DP(dp[m]+1,1e9);
        DP[0]=0;

        for(int i=0;i<dp[m];i++){
            for(int j=0;j<n;j++){
                if(i+v[j]>dp[m])continue;
                DP[i+v[j]] = min( DP[i+v[j]] , DP[i]+len[j] );
            }
        }

        cout<<"Case "<<++cnt<<": "<<DP[dp[m]]<<endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3144
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define int long long
using namespace std;

int N, p[105];
string words[105];
string s;
int dp1[500], dp2[3000];

bool same(int x, int idx){
  
  if( (int)s.size() - x < (int)words[idx].size() ) return false;
  
  for(int i=0;i<(int)words[idx].size();i++){
    
    if( s[x+i] != words[idx][i] ) return false;
    
  }

  return true;
}

void solve(){
  
  memset(dp1,-1,sizeof(dp1));
  
  dp1[0] = 0;
  
  for(int i=0;i<(int)s.size();i++){
    
    if( dp1[i] == -1 ) continue;
    
    for(int j=0;j<N;j++){
      
      if( same( i, j ) == true ){
	
	int len = (int)words[j].size();
	
	dp1[i+len] = max( dp1[i+len], dp1[i] + p[j] );
	
      }
      
    }
    
  }
  
  int P = dp1[(int)s.size()];
  
  const int INF = 1e9;
  
  for(int i=0;i<=P;i++) dp2[i] = INF;
  
  dp2[0] = 0;
  
  int cnt = 2005;
  
  while(cnt--){
    
    for(int i=0;i<N;i++){
      
      int len = (int)words[i].size();
      
      for(int j=P;j>=0;j--){
	
	if( dp2[j] == INF ) continue;
	
	dp2[j+p[i]] = min( dp2[j+p[i]], dp2[j] + len );
	
      }
      
    }
    
  }
  
  cout<<dp2[P]<<endl;
  
}

signed main(){
  
  int casenum = 1;
  
  while(1){
    
    cin>>N;
    if( N == 0 ) break;
    
    for(int i=0;i<N;i++) cin>>words[i]>>p[i];
    
    cin>>s;
    
    cout<<"Case "<<casenum<<": ";
    
    solve();

    casenum++;
  }
  
  return 0;
}
accuracy: 1
time_ms: 2830
memory_kb: 3212
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

template<typename T1,typename T2> void chmin(T1 &a,T2 b){if(a>b) a=b;};
template<typename T1,typename T2> void chmax(T1 &a,T2 b){if(a<b) a=b;};

signed main(){
  Int n;
  Int cnt=0;
  while(cin>>n,n){
    vector<string> ss(n);
    vector<Int> ls(n),vs(n);
    for(Int i=0;i<n;i++) cin>>ss[i]>>vs[i],ls[i]=ss[i].size();
    string t;
    cin>>t;
    Int m=t.size();

    const Int INF = 1e9;
    vector<Int> dp1(m+1,-INF);
    dp1[0]=0;

    for(Int i=0;i<m;i++){
      for(Int j=0;j<n;j++){
	if(i+ls[j]>m) continue;
	if(t.substr(i,ls[j])!=ss[j]) continue;
	chmax(dp1[i+ls[j]],dp1[i]+vs[j]);
      }
    }

    vector<Int> dp2(dp1[m]+1,INF);
    dp2[0]=0;
    for(Int i=0;i<dp1[m];i++){
      for(Int j=0;j<n;j++){
	if(i+vs[j]>dp1[m]) continue;
	chmin(dp2[i+vs[j]],dp2[i]+ls[j]);
      }      
    }
    
    cout<<"Case "<<++cnt<<": "<<dp2[dp1[m]]<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3156
final_rank: 7

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;



 int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const long long  int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}

vector<pair<int, int>>get_connect(int N, int x, int y) {
	vector<pair<int,int>>anss;
	{
		int ax=x-1;
		int ay=y;
		anss.emplace_back(ax,ay);
	}
	{
		int ax=x+1;
		int ay=y;
		anss.emplace_back(ax, ay);

	}

	//lu
	{
		int ax,ay;
		if (y < N) {
			ax=x-1;
			ay=y-1;
		}
		else {
			ax=x;
			ay=y-1;
		}
		anss.emplace_back(ax, ay);

	}

	//ru
	{
		int ax,ay;
		if (y < N) {
			ax=x;
			ay=y-1;
		}
		else {
			ax=x+1;
			ay=y-1;
		}
		anss.emplace_back(ax, ay);

	}

	//ld
	{
		int ax,ay;
		if (y < N - 1) {
			ax=x;
			ay=y+1;
		}
		else {
			ax=x-1;
			ay=y+1;
		}
		anss.emplace_back(ax, ay);

	}
	//rd
	{
		int ax,ay;
		if (y < N - 1) {
			ax=x+1;
			ay=y+1;
		}
		else {
			ax=x;
			ay=y+1;
		}
		anss.emplace_back(ax, ay);

	}
	vector<pair<int,int>>real_anss;
	for (auto ans : anss) {
		int ax(ans.first);
		int ay(ans.second);
		bool ok=true;
		if(ay<0||ay>=2*N-1)ok=false;
		if (ay < N) {
			if(ax<0||ax>=N+ay)ok=false;
		}
		else {
			if (ax < 0 || ax>=3*N-ay-2)ok=false;
		}
		if(ok)real_anss.emplace_back(ans);
	}
	return real_anss;
}


template<typename T>
vector<vector<T>> keisann(const vector<vector<T>>l, const vector<vector<T>>r) {
	vector<vector<T>>ans(l.size(), vector<T>(r[0].size()));
	assert(l[0].size() == r.size());
	for (unsigned int h = 0; h < l.size(); ++h) {
		for (unsigned int i = 0; i < r.size(); ++i) {
			for (unsigned int w = 0; w < r[0].size(); ++w) {

				ans[h][w] += l[h][i] * r[i][w];
			}
		}
	}
	return ans;
}

template<typename T>
vector<vector<T>>powgyou(vector<vector<T>>a, const long long int n) {
	assert(a.size() == a[0].size());
	if (!n) {
		vector<vector<T>>e(a.size(), vector<T>(a[0].size()));
		for (unsigned int i = 0; i < a.size(); ++i) {
			e[i][i] = 1;
		}
		return e;
	}
	if (n == 1)return a;
	else {
		vector<vector<T>>ans(a.size(), vector<T>(a[0].size(), 0));
		ans = powgyou(a, n / 2);
		ans = keisann(ans, ans);
		if (n % 2) {
			ans = keisann(ans, a);
		}
		return ans;
	}
}


int main() {
	int case_id=0;
	while (true) {
		case_id++;
		int N;cin>>N;
		if(!N)break;
		map<string,int>mp;
		for (int i = 0; i < N; ++i) {
			string st;cin>>st;
			int n;cin>>n;
			mp[st]=n;
		}


		int need_num = -1;
		{
			string st; cin >> st;
			vector<int>nums(st.size() + 1, -100000);
			nums[0] = 0;
			for (int i = 0; i < st.size(); ++i) {
				for (auto m : mp) {
					if (st.substr(i, m.first.size()) == m.first) {
						nums[i + m.first.size()] = max(nums[i + m.first.size()], nums[i] + m.second);
					}
				}
			}
			need_num=nums[st.size()];
		}
		vector<int>dp(need_num+10000,100000);
		dp[0]=0;
		for (int i = 0; i < need_num; ++i) {
			for (auto m : mp) {
				dp[i+m.second]=min(dp[i+m.second],int(dp[i]+m.first.size()));
			}
		}
		cout<<"Case "<<case_id<<": "<<dp[need_num]<<endl;
	}
	
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 11128
final_rank: 17

code_snippet: #include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	char name[101];
	int length,value;
};

struct Data{
	Data(int arg_left,int arg_sum_value){
		left = arg_left;
		sum_value = arg_sum_value;
	}
	bool operator<(const struct Data &arg) const{
		return left > arg.left;
	}

	int left,sum_value;
};

int N;
Info info[100];
char line[201];
int case_number = 1,line_length;


void func(){

	int tmp_length;
	for(int i = 0; i < N; i++){
		scanf("%s %d",info[i].name,&info[i].value);
		for(tmp_length = 0; info[i].name[tmp_length] != '\0'; tmp_length++);
		info[i].length = tmp_length;
	}

	scanf("%s",line);
	for(tmp_length = 0; line[tmp_length] != '\0'; tmp_length++);
	line_length = tmp_length;


	int max_value[line_length+1];
	for(int i = 0; i <= line_length; i++)max_value[i] = 0;

	priority_queue<Data> Q;
	Q.push(Data(0,0));

	bool FLG;

	while(!Q.empty()){

		if(Q.top().left == line_length){
			Q.pop();
		}else if(Q.top().sum_value < max_value[Q.top().left]){
			Q.pop();
		}else{

			for(int i = 0; i < N; i++){
				if(Q.top().left+info[i].length-1 >= line_length)continue;

				FLG = true;
				for(int k = 0; k < info[i].length; k++){
					if(line[Q.top().left+k] != info[i].name[k]){
						FLG = false;
						break;
					}
				}


				if(FLG){
					if(max_value[Q.top().left+info[i].length] < Q.top().sum_value+info[i].value){
						max_value[Q.top().left+info[i].length] = Q.top().sum_value+info[i].value;
						Q.push(Data(Q.top().left+info[i].length,max_value[Q.top().left+info[i].length]));
					}
				}
			}

			Q.pop();
		}
	}

	int digit = max_value[line_length];

	int dp[digit+1];
	int next_dp[digit+1];

	for(int i = 1; i <= digit; i++){
		dp[i] = BIG_NUM;
		next_dp[i] = BIG_NUM;
	}

	dp[0] = 0;
	next_dp[0] = 0;

	for(int i = 0; i < N; i++){

		FLG = true;
		for(int k = 0; k < N; k++){
			if(k == i)continue;

			if(info[k].value == info[i].value && info[k].length < info[i].length){
				FLG = false;
				break;
			}
		}

		if(!FLG)continue;

		for(int num = 1; num*info[i].value <= digit; num++){
			for(int k = digit; k-num*info[i].value >= 0; k--){
				if(dp[k-num*info[i].value] != BIG_NUM){
					next_dp[k] = min(next_dp[k],dp[k-num*info[i].value]+num*info[i].length);
				}
			}
		}
		for(int k = 1; k <= digit; k++)dp[k] = next_dp[k];
	}

	printf("Case %d: %d\n",case_number,next_dp[digit]);

	case_number++;
}


int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3272
final_rank: 12

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	char name[101];
	int length,value;
};

struct Data{
	Data(int arg_left,int arg_sum_value){
		left = arg_left;
		sum_value = arg_sum_value;
	}
	bool operator<(const struct Data &arg) const{
		return left > arg.left;
	}

	int left,sum_value;
};

int N;
Info info[100];
char line[201];
int case_number = 1,line_length;


void func(){

	int tmp_length;
	for(int i = 0; i < N; i++){
		scanf("%s %d",info[i].name,&info[i].value);
		for(tmp_length = 0; info[i].name[tmp_length] != '\0'; tmp_length++);
		info[i].length = tmp_length;
	}

	scanf("%s",line);
	for(tmp_length = 0; line[tmp_length] != '\0'; tmp_length++);
	line_length = tmp_length;


	int max_value[line_length+1];
	for(int i = 0; i <= line_length; i++)max_value[i] = 0;

	priority_queue<Data> Q;
	Q.push(Data(0,0));

	bool FLG;

	while(!Q.empty()){

		if(Q.top().left == line_length){
			Q.pop();
		}else if(Q.top().sum_value < max_value[Q.top().left]){
			Q.pop();
		}else{

			for(int i = 0; i < N; i++){
				if(Q.top().left+info[i].length-1 >= line_length)continue;

				FLG = true;
				for(int k = 0; k < info[i].length; k++){
					if(line[Q.top().left+k] != info[i].name[k]){
						FLG = false;
						break;
					}
				}


				if(FLG){
					if(max_value[Q.top().left+info[i].length] < Q.top().sum_value+info[i].value){
						max_value[Q.top().left+info[i].length] = Q.top().sum_value+info[i].value;
						Q.push(Data(Q.top().left+info[i].length,max_value[Q.top().left+info[i].length]));
					}
				}
			}

			Q.pop();
		}
	}

	int digit = max_value[line_length];

	int dp[digit+1];
	int next_dp[digit+1];

	for(int i = 1; i <= digit; i++){
		dp[i] = BIG_NUM;
		next_dp[i] = BIG_NUM;
	}

	dp[0] = 0;
	next_dp[0] = 0;

	for(int i = 0; i < N; i++){
		for(int num = 1; num*info[i].value <= digit; num++){
			for(int k = digit; k-num*info[i].value >= 0; k--){
				if(dp[k-num*info[i].value] != BIG_NUM){
					next_dp[k] = min(next_dp[k],dp[k-num*info[i].value]+num*info[i].length);
				}
			}
		}
		for(int k = 1; k <= digit; k++)dp[k] = next_dp[k];
	}

	printf("Case %d: %d\n",case_number,next_dp[digit]);

	case_number++;
}


int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 3356
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;

int N,M;
string w[111];
int p[111];
string S;
int cost[111];

typedef pair<int,int> P;
vector<P> H[211];
set<int> dp[211];
int dp2[2111];
void init(){
  for(int i=0;i<=M;i++) H[i].clear();
  for(int i=0;i<=M;i++) dp[i].clear();
  memset( dp2, -1,sizeof( dp2 ) );
}


void solve1(){
  dp[0].insert( 0 );
  for(int i=0;i<M;i++){
    for( P np : H[i] ) {
      int to = np.first;
      for( int num : dp[i] ){
        int nc = np.second + num;
        dp[to].insert( nc );
      }
    }
  }
}

const int INF = (1<<29);
int solve2(int num){
  int &ret = dp2[num];
  if( ret != -1 ) return ret;
  if( num == 0 ) return ret = 0;
  ret = INF;
  for( int i=0;i<N;i++ )
    if( num - p[i] >= 0 )
      ret = min( ret, solve2( num - p[i] ) + cost[i] );
  return ret;
}

int main(){
  int ttt=1;
  while( cin >> N && N ){
    map<string,vector<int>> mv;
    for(int i=0;i<N;i++){
      cin >> w[i] >> p[i];
      cost[i] = w[i].size();
      mv[w[i]].push_back( i );
    }
    cin >> S;
    M = S.size();
    init();
    
    for(int i=0;i<S.size();i++){
      string s = "";
      for(int j=i;j<S.size();j++){
        s += S[j];
        for( int id : mv[s] ) 
          H[i].push_back( P( j+1, p[id] ) );        
      }
    }

    int res = M;
    solve1();
    if( !dp[M].empty() ) res = min( res, solve2( *dp[M].rbegin() ) );

    cout << "Case " << ttt++ << ": ";
    cout << res << endl;
  }
}
accuracy: 1
time_ms: 960
memory_kb: 13964
final_rank: 19

code_snippet: #include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int dp[250][2400], dp2[2400];
string S[1000], T; int v[1000];
int main() {
	int cnt = 0;
	while (true) {
		int n; cin >> n; if (n == 0)break; cnt++;
		for (int i = 0; i < n; i++)cin >> S[i] >> v[i]; cin >> T;
		for (int i = 0; i < 250; i++) { for (int j = 0; j < 2400; j++)dp[i][j] = 0; }dp[0][0] = 1;
		for (int i = 0; i < 2400; i++) { dp2[i] = 999999999; }dp2[0] = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < 2400 - v[i]; j++) {
				dp2[j + v[i]] = min(dp2[j + v[i]], dp2[j] + (int)S[i].size());
			}
		}
		for (int i = 0; i < T.size(); i++) {
			for (int j = 0; j < 2400; j++) {
				if (dp[i][j] == 0)continue;
				for (int k = 0; k < n; k++) {
					if (i + S[k].size() > T.size())continue;
					if (T.substr(i, S[k].size()) != S[k])continue;
					dp[i + S[k].size()][j + v[k]] = 1;
				}
			}
		}
		int minx = 999999999;
		for (int i = 0; i < 2400; i++) {
			if (dp[T.size()][i] == 1)minx = dp2[i];
		}
		if (minx == 999999999)minx = -1;
		cout << "Case " << cnt << ": " << minx << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 3190
memory_kb: 5580
final_rank: 20

code_snippet: #include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int n, l[109]; string s[109], t;
int main() {
	int cnt = 0;
	while (cin >> n, n) {
		for (int i = 0; i < n; i++) cin >> s[i] >> l[i];
		cin >> t;
		vector<int> dp1(t.size() + 1);
		for (int i = 1; i <= t.size(); i++) {
			dp1[i] = 0;
			for (int j = 0; j < n; j++) {
				if (s[j].size() <= i && t.substr(i - s[j].size(), s[j].size()) == s[j]) {
					dp1[i] = max(dp1[i], dp1[i - s[j].size()] + l[j]);
				}
			}
		}
		int res = dp1[t.size()];
		vector<vector<int> > dp2(n + 1, vector<int>(res + 1, 999999999));
		dp2[0][0] = 0;
		for (int i = 1; i <= n; i++) {
			for (int j = 0; j <= res; j++) {
				dp2[i][j] = dp2[i - 1][j];
				if (j >= l[i - 1]) dp2[i][j] = min(dp2[i][j], dp2[i][j - l[i - 1]] + (int)s[i - 1].size());
			}
		}
		cout << "Case " << ++cnt << ": " << dp2[n][res] << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3400
final_rank: 11

code_snippet: //
//  main.cpp
//  160324
//
//  Created by ?加寿 on 16/3/24.
//  Copyright ? 2016年 chenhuan001. All rights reserved.
//

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

#define N 110
map<string,int> cao;

string saves[N];
int savek[N];
int main(int argc, const char * argv[]) {
    int n;
    int tt=1;
    while(cin>>n&&n)
    {
        cao.clear();
        for(int i=0;i<n;i++)
        {
            string tmp;
            int key;
            cin>>tmp>>key;
            saves[i] = tmp;
            savek[i] = key;
            cao[tmp] = max(cao[tmp],key);
        }
        //第一个背包
        char g[222];
        scanf("%s",g);
        int len=strlen(g);
        int dp[22200];
        memset(dp,-1,sizeof(dp));
        dp[0]=0;
        for(int i=0;i<len;i++)
        {
            //?个地方有点??
            //dp[i+1] = max(dp[i+1],dp[i]);
            if(dp[i]==-1)
            {
                continue;
            }
            string str="";
            for(int j=i;j<len;j++)
            {
                str+=g[j];
                if(cao[str] != 0)
                {
                    dp[j+1] = max(dp[j+1],dp[i]+cao[str]);
                }
            }
        }
        int mx=dp[len];
        //再用2000的背包.
        for(int i=0;i<2002;i++)
            dp[i] = 1e6;
        dp[0] = 0;
        //无限背包
        for(int i=0;i<mx;i++)
        {
            for(int j=0;j<n;j++)
            {
                int sz=saves[j].length();
                dp[ i+savek[j] ] = min(dp[i+savek[j]],dp[i]+sz);
            }
        }
        printf("Case %d: ",tt++);
        cout<<dp[mx]<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 5404
final_rank: 16

code_snippet: #include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<iostream> 

using namespace std;

	int n;
	string s[205];
	string ch;
	int x[2005];
	int f[2005];
	int v[1005];
	int w[1005];
	int L;
	int V;
	string nowch;
	int tot=0;

int main()
{
	while (1)
	{	
		scanf("%d",&n);
		tot++;
		if (!n)
		{
			break;
		}
		for (int i=1;i<=n;i++)
		{
			cin>>s[i]>>v[i];
			w[i]=s[i].size();
		}
		cin>>ch;
		L=ch.size();
		memset(f,-1,sizeof(f));
		f[0]=0;
		for (int i=0;i<=L;i++)
		{
			for (int j=1;j<=n;j++)
			{
				if (i-w[j]>=0)
				{
					if (f[i-w[j]]>=0 && ch.substr(i-w[j],w[j])==s[j])
					{
						f[i]=max(f[i],f[i-w[j]]+v[j]);
					}
				}
			}
		}
		
		V=f[L];
		memset(f,0x3f3f3f3f,sizeof(f));
		f[0]=0;
		for (int i=1;i<=n;i++)
		{
			for (int j=v[i];j<=V;j++)
			{
				f[j]=min(f[j],f[j-v[i]]+w[i]);
			}	
		}
		printf("Case %d: %d\n",tot,f[V]);
	}
	
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1308
final_rank: 5

code_snippet: #include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>

using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 2000;

int N,v[maxn],len[maxn];
int dp[maxn];

string s[maxn],str;

int main()
{
    int cas = 1;
    while(cin >> N && N)
    {
        for(int i=0;i<N;i++)
        {
            cin >> s[i] >> v[i];
            len[i] = s[i].length();
        }
        cin >> str;
        int length = str.length();

        for(int i=0;i<=length;i++) dp[i] = -INF;
        dp[0] = 0;

        for(int i=0;i<=length;i++)
        {
            for(int j=0;j<N;j++)
            {
                int End = i - len[j];
                if(End>=0 && dp[End]>=0 && str.substr(End,len[j]) == s[j])
                    {dp[i] = max(dp[i],dp[End]+v[j]);}
            }
        }

        int mx = dp[length];

        for(int i=0;i<=mx;i++) dp[i] = INF;
        dp[0] = 0;

        for(int i=0;i<N;i++)
        {
            for(int j=0;j<=mx-v[i];j++)
                dp[j+v[i]] = min(dp[j+v[i]] , dp[j]+len[i]);
        }
        cout << "Case "<<cas++<< ": " << dp[mx] << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 1272
final_rank: 4

code_snippet: #include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
int t;
int n;
int m;
char a[110][110];
int shu[110];
int len[110];
char s[210];
int f[2100];
int ff[220];
int PIPEI(){
	memset(ff,0,sizeof(ff));
	int w=strlen(s);
	for(int i=0;i<w;i++){
		for(int j=1;j<=n;j++){
			if(len[j]<=i+1){
				int v=1;
				for(int k=0;k<len[j];k++){
					if(s[i-len[j]+1+k]!=a[j][k]){
						v=0;
						break;
					}
				}
				if(v)ff[i+1]=max(ff[i+1],ff[i+1-len[j]]+shu[j]);
			}
		}
	}
	return ff[w];
}
int main(){
	scanf("%d",&n);
	while(n){
		t++;
		for(int i=1;i<=n;i++)scanf(" %s %d",&a[i][0],&shu[i]);
		for(int i=1;i<=n;i++)len[i]=strlen(a[i]);
		scanf(" %s",s);
		m=PIPEI();
//		printf("m=%d\n",m);
		memset(f,30,sizeof(f));
		f[0]=0;
		for(int i=1;i<=n;i++){
			for(int j=shu[i];j<=m;j++){
				f[j]=min(f[j],f[j-shu[i]]+len[i]);
			}
		}
		printf("Case %d: %d\n",t,f[m]);
		scanf("%d",&n);
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1224
final_rank: 1

code_snippet: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

int n;
char s[210];
char subs[210];

struct word
{
    char str[110];
    int l;
}w[110];
int len[110];

int dp0[2010];
int dp[2010];

void sub(int st,int ed)
{
    int i;
    for(i=st;i<=ed;i++)
        subs[i-st]=s[i];
    subs[i-st]='\0';
}

int main()
{
    int cou=1;
    while(~scanf("%d",&n)&&n)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%s%d",w[i].str,&w[i].l);
            len[i]=strlen(w[i].str);
        }
        scanf("%s",s);
        int len0=strlen(s);
        int start=0;
        int v=0;
        for(int i=0;i<=len0;i++)
            dp0[i]=-1*(0x3f3f3f3f);
        dp0[0]=0;
        for(int i=1;i<=len0;i++)
        {
            for(int j=0;j<n;j++)
            {
                int ed=i-len[j];
                sub(ed,ed+len[j]-1);
                if(ed>=0&&dp0[ed]>=0&&strcmp(w[j].str,subs)==0)
                    dp0[i]=max(dp0[i],dp0[ed]+w[j].l);
            }
        }
        v=dp0[len0];
        for(int i=0;i<=v;i++)
            dp[i]=0x3f3f3f3f;
        dp[0]=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<=v;j++)
            {
                if(w[i].l<=j)
                    dp[j]=min(dp[j],dp[j-w[i].l]+len[i]);
            }
        }
        printf("Case %d: %d\n",cou++,dp[v]);
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1224
final_rank: 3

code_snippet: /*author: birdstorm*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
const int INF = 0x3f3f3f3f;
string s[MAXN], ans;
int n, len[MAXN], a[MAXN];
int dp[MAXN], dp2[MAXN];
int main() {
    int cs = 1;
    while(scanf("%d",&n) != EOF && n) {
        for(int i = 0; i < n; i ++) {
            cin >> s[i] >> a[i];
            len[i] = s[i].length();
        }
        cin >> ans;
        int length = ans.length();
        for(int i = 0; i <= length; i ++) {
            dp[i] = -INF;
        }
        dp[0] = 0;
        for(int i = 0; i <= length; i ++) {
            for(int j = 0; j < n; j ++) {
                int End = i - len[j];
                if(End >= 0 && dp[End] >= 0 && ans.substr(End, len[j]) == s[j]) {
                    dp[i] = max(dp[i], dp[End] + a[j]);
                }
            }
        }
        int sz = dp[length];
        for(int i = 0; i <= sz; i ++) {
            dp2[i] = INF;
        }
        dp2[0] = 0;
        for(int i = 0; i < n; i ++) {
            for(int j = 0; j <= sz - a[i]; j ++) {
                dp2[j+a[i]] = min(dp2[j+a[i]], dp2[j]+len[i]);
            }
        }
        printf("Case %d: %d\n",cs++,dp2[sz]);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3372
final_rank: 10

code_snippet: /**
	???南?不好,却道,此心安?是吾?。
**/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
	for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)

const int maxn = 300+20;

char s[maxn][maxn],a[maxn];
int len[maxn],p[maxn],n;
int dp[200*10+30];

int solve(int M)
{
	for(int i=0;i<=M;i++)
		dp[i] = inf;
	dp[0]=0;
	for(int i=0;i<n;i++)
		for(int j=0;j+p[i]<=M;j++)
			dp[j+p[i]] = min(dp[j+p[i]],dp[j]+len[i]);
	return dp[M];
}

int va[maxn];

int main(){
//	freopen("input.txt","r",stdin);
	int CASE=0;
	while(~scanf("%d",&n))
	{
		if(!n) break;
        clr(va,-1);
        for(int i=0;i<n;i++)
		{
			scanf("%s%d",s[i],&p[i]);
			len[i] = strlen(s[i]);
		}
		scanf("%s",a);
        va[0] = 0;
        for(int i=0;a[i];i++) if(va[i]!=-1)
		{
            for(int j=0;j<n;j++)
			{
				int is=1;
				for(int k=0;k<len[j];k++)
					if( a[i+k] != s[j][k] )
					{
						is=0;
						break;
					}
				if(is) va[i+len[j]] = max(va[i+len[j]],va[i]+p[j]);
			}
		}
		int M = va[strlen(a)];
//		debug(M);
        int ans = solve(M);
        printf("Case %d: %d\n",++CASE,ans);
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1240
final_rank: 2