日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Build String(CF-237E)

發(fā)布時間:2025/3/17 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Build String(CF-237E) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Problem Description

You desperately need to build some string t. For that you've got n more strings s1,?s2,?...,?sn. To build string t, you are allowed to perform exactly |t| (|t| is the length of string t) operations on these strings. Each operation looks like that:

  • choose any non-empty string from strings s1,?s2,?...,?sn;
  • choose an arbitrary character from the chosen string and write it on a piece of paper;
  • remove the chosen character from the chosen string.

Note that after you perform the described operation, the total number of characters in strings s1,?s2,?...,?sn decreases by 1. We are assumed to build string t, if the characters, written on the piece of paper, in the order of performed operations form string t.

There are other limitations, though. For each string si you know number ai — the maximum number of characters you are allowed to delete from string si. You also know that each operation that results in deleting a character from string si, costs i rubles. That is, an operation on string s1 is the cheapest (it costs 1 ruble), and the operation on string sn is the most expensive one (it costs n rubles).

Your task is to count the minimum amount of money (in rubles) you will need to build string t by the given rules. Consider the cost of building string t to be the sum of prices of the operations you use.

Input

The first line of the input contains string t — the string that you need to build.

The second line contains a single integer n (1?≤?n?≤?100) — the number of strings to which you are allowed to apply the described operation. Each of the next n lines contains a string and an integer. The i-th line contains space-separated string si and integer ai (0?≤?ai?≤?100). Number ai represents the maximum number of characters that can be deleted from string si.

All strings in the input only consist of lowercase English letters. All strings are non-empty. The lengths of all strings do not exceed 100 characters.

Output

Print a single number — the minimum money (in rubles) you need in order to build string t. If there is no solution, print -1.

Examples

Input

bbaze
3
bzb 2
aeb 3
ba 10

Output

8

Input

abacaba
4
aba 2
bcc 1
caa 2
bbb 5

Output

18

Input

xyz
4
axx 8
za 1
efg 4
t 1

Output

-1

題意:給出一個字符串 str,然后有 n 個可供使用的字符串,現(xiàn)在在 n 個可用字符串中選取一定的字符組成字符串 str,從第 i 個串中拿一個字符的代價是 i 且最多拿 num[i] 個,求組成目標(biāo)字符串的最小花費

思路:最小費用流

設(shè)置一個超級源點與超級匯點,從源點到 26 個字符建邊,容量記為字符串 str 的個數(shù),費用為 0,然后將每個字符向 n 個字符串建邊,對于第 i 個串來說,容量為該串中相應(yīng)字符的個數(shù),費用為 i,最后對每個模式串向匯點建邊,容量為 num[i],費用為 0

最后如果出現(xiàn)滿流,則說明可以構(gòu)造出 str 串

Source Program

#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #include<bitset> #define EPS 1e-9 #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LL long long const int MOD = 1E9+7; const int N = 10000+5; const int dx[] = {-1,1,0,0,-1,-1,1,1}; const int dy[] = {0,0,-1,1,-1,1,-1,1}; using namespace std;struct Edge{int from,to;int cap,flow;int cost;int next; }edge[N]; int head[N],tot; char str[N]; int bucket[27];//str串中字符個數(shù) int G[N][27];//n個字符串每串的字符個數(shù) int num[N];//n個字符串每串最多取的個數(shù) int pre[N];//記錄從S到i的最小費用路徑上的最后一條弧編號 int dis[N]; bool vis[N]; bool SPFA(int S,int T) {queue<int> Q;memset(dis,INF,sizeof(dis));memset(vis,false,sizeof(vis));memset(pre,-1,sizeof(pre));dis[S]=0;Q.push(S);while(!Q.empty()) {int x=Q.front();Q.pop();vis[x]=false;for(int i=head[x];i!=-1;i=edge[i].next) {int y=edge[i].to;int cost=edge[i].cost;int cap=edge[i].cap;int flow=edge[i].flow;if(dis[y]>dis[x]+cost&&cap>flow) {dis[y]=dis[x]+cost;pre[y]=i;if(!vis[y]){vis[y]=true;Q.push(y);}}}}return pre[T]!=-1; } void MCMF(int S,int T,int &flow,int &cost){flow=0;cost=0;while(SPFA(S,T)){//每次尋找花銷最小的路徑int minn=INF;for(int i=pre[T];i!=-1;i=pre[edge[i^1].to])//尋找最小增廣流minn=min(minn,edge[i].cap-edge[i].flow);for(int i=pre[T];i!=-1;i=pre[edge[i^1].to]) {edge[i].flow+=minn;edge[i^1].flow-=minn;cost+=edge[i].cost*minn;//增廣流的花銷}flow+=minn;//總流量增加} }void addEdge(int from,int to,int cap,int flow,int cost){edge[tot].from=from;edge[tot].to=to;edge[tot].cap=cap;edge[tot].flow=flow;edge[tot].cost=cost;edge[tot].next=head[from];head[from]=tot++; }int main(){scanf("%s",str);int len=strlen(str);for(int i=0;i<len;i++)//統(tǒng)計str串中字符的個數(shù)bucket[str[i]-'a'+1]++;int n;scanf("%d",&n);for(int i=1;i<=n;i++){char temp[N];scanf("%s%d",temp,&num[i]);int length=strlen(temp);for(int j=0;j<length;j++)G[i][temp[j]-'a'+1]++;//統(tǒng)計第i個字符串中字符的個數(shù)}tot=0;memset(head,-1,sizeof(head));int S=0,T=26+n+1;for(int i=1;i<=26;i++){if(bucket[i]==0)continue;//源點到26個字符addEdge(S,i,bucket[i],0,0);//正向邊addEdge(i,S,0,0,0);//反向邊f(xié)or(int j=1;j<=n;j++){if(G[j][i]==0)continue;//26個字符到n個字符串a(chǎn)ddEdge(i,26+j,G[j][i],0,j);//正向邊addEdge(26+j,i,0,0,-j);//反向邊}}for(int i=1;i<=n;i++){//n個字符串到匯點addEdge(26+i,T,num[i],0,0);//正向邊addEdge(T,26+i,0,0,0);//反向邊}int flow,cost;MCMF(S,T,flow,cost);if(flow!=len)//不滿流printf("-1\n");else//滿流printf("%d\n",cost);return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的Build String(CF-237E)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。