亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

UESTC1565 Smart Typist

系統 1573 0

UESTC1565 Smart Typist

Time Limit:? 2000 ms ?Memory Limit:? 65536 kB ?Solved:? 10? Tried:? 49

Description

?

The most mysterious organization in Chani is “Related Department”. It is related to almost everything, and has branches almost everywhere. Events always have relation with it. Whenever disasters happen, “Related Department” would stand out to commit its responsibility. The members of “Related Department” are called “Related person”. However, ordinary people have no idea about who is “Related person” since their information is national secret.
Xiaoming is the top typist in Chani. The legend is that he could type 400 words per minute. Today he accepted an order from a man who said that he is a “Related person”. That “Related person” asked Xiaoming to turn many paper documents into electronic files. For reasons of security, Xiaoming has to use a special device which has limited functions. With the special device, Xiaoming can only perform such operations:
1. Creating a new file. It takes a quite short time that we ignore the time for it.
2. Replacing current file with some file finished before. A file is allowed to be used to replace another one only after it is finished and won’t be edited later.
3. Deleting any letter(s) in current file.
4. Inserting letter(s) at arbitrary position in current file.
Note that, the keyboard for this device is so strange that the time for typing different letter may be different.
Xiaoming is somewhat afraid of dealing with “Related person”, so he wants to accomplish this order as soon as possible. Knowing time needed for each operation, Xiaoming is trying to make the best plan which spends the minimum time.

?

Input

?


The first line of the input is T (no more than 50), which stands for the number of test cases you need to solve.
Each case begins with two integers, repCost and delCost (1 <= repCost, delCost <= 50), time needed to replace current file, time for deleting one letter. On the second line, there are 26 numbers representing the time for typing each letter from ‘a’ to ‘z’, each number is between 1 and 50.
Then a line with an integer N (1 <= N <= 50) is given indicating the number of files.
N lines followed. Each line gives a string only consisting of letters ‘a’-‘z’ to represent a file. The maximum length of the strings is not greater than 50.

?

Output

?


For every test case, you should output "Case #k: c" first in a line, where k indicates the case number and counts from 1, c is the minimum time needed.

?

Simple Input

?

2
1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2
aaab
aaaa
10 10
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2
aaab
aaaa

?

Simple Output

?

Case #1: 7
Case #2: 8

**************************************************************

題目大意:某個打字員要打n個字符串,有如下操作:

  1.創建一個一個文件,不計時間。

  2.用一個已經存在的文件替換當前文件,花費為rep

  3.刪除某些字符,每刪除一個字符的花費為del

  4.在當前文件任意位置增加字符,花費為val[字符]。

求打完這些字符串所要的最小花費。

解題思路:這道題,怎么說呢。我們把每個字符串當一個節點,一個字符串到另一個字符串的變化花費計算出來,然后再有一個最終節點連到所有的字符串,權值為打這個字符串的花費。那么,問題轉化為這個有向圖中的最小樹形圖。建圖很簡單,求最小樹形圖也不過是套用朱劉算法的模板,然而令人糾結的是怎么把一個字符串變化到另一個字符串的花費,要不是這個,我也不會寫這道題。這個花費很難算啊,經過我、YYB、ZYC一個晚上的思考,終于相處了這個dp過程,真是艱辛苦楚。

直接考慮s1變化到s2的dp:

dp[0][1~len1]=del*len1代表全部刪除,以后一個一個匹配進來。

dp[i][0]=dp[i-1][0]+val[i];

dp[i][j],當s1的第i個==s2的第j個字母,dp[i][j]=dp[i-1][j-1]-del;當s1的第i個!=s2的第j個字母,dp[i][j]=min(dp[i][j-1],dp[i-1][j]+val[i]);

dp很難想 真心的。

        //#pragma comment(linker, "/STACK:65536000")

#include <map>

#include <stack>

#include <queue>

#include <math.h>

#include <vector>

#include <string>

#include <fstream>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <iostream>

#include <algorithm>

#define N 55

#define M 30

#define E

#define inf 0x3f3f3f3f

#define dinf 1e10

#define linf (LL)1<<60

#define eps 1e-8

#define LL long long

#define clr(a,b) memset(a,b,sizeof(a))

#define D(a) ((a)*(a))

using namespace std;



int n;

int del,rep,val[M],gra[N][N];

string s[N];

int dp[N][N];

int pre[N],vis[N],cnt,ced[N];//ced數組用來縮點用的



void dpt(int a,int b)

{

    string s1=s[a],s2=s[b];

	int len1=s1.size(),len2=s2.size();

	for(int i=0;i<=len1;i++)dp[0][i]=len1*del;

	for(int i=1;i<=len2;i++)

    {

        dp[i][0]=dp[i-1][0]+val[s2[i-1]-'a'];

        for(int j=1;j<=len1;j++)

            if(s1[j-1]==s2[i-1])

                dp[i][j]=dp[i-1][j-1]-del;

            else

                dp[i][j]=min(dp[i][j-1],dp[i-1][j]+val[s2[i-1]-'a']);

    }

    gra[a][b]=dp[len2][len1]+rep;

}



void dfs(int s)//dfs判是否有解

{

    vis[s]=1;cnt++;

    for(int i=1;i<=n;i++)

        if(gra[s][i]<dinf&&!vis[i])

            dfs(i);

}



int ZHULIU(void)

{

    clr(ced,0);int ans=0;

    int i,j,k;

    do

    {

        for(i=2;i<=n;i++)//清除自環,以及求每個點的入邊

        {

            if(ced[i])continue;

            pre[i]=1;

            for(j=2;j<=n;j++)

                if(j!=i&&!ced[j]&&gra[pre[i]][i]>gra[j][i])

                    pre[i]=j;

        }

        for(i=2;i<=n;i++)

        {

            if(ced[i])continue;

            clr(vis,0);

            for(j=i;j!=1&&!vis[j];j=pre[j])vis[j]=1;//尋找環,被vis標記的是環內的點

            if(j==1)continue;

            ans+=gra[pre[j]][j];

            for(i=pre[j];i!=j;i=pre[i])//把環里的權值加到ans中去

                ans+=gra[pre[i]][i],ced[i]=1;

            for(k=1;k<=n;k++)//這個和下面那個for在縮點

                if(!ced[k]&&gra[k][j]<inf)

                    gra[k][j]-=gra[pre[j]][j];

            for(i=pre[j];i!=j;i=pre[i])

                for(k=1;k<=n;k++)

                {

                    if(ced[k])continue;

                    gra[j][k]=min(gra[j][k],gra[i][k]);

                    if(gra[k][i]<inf)

                        gra[k][j]=min(gra[k][j],gra[k][i]-gra[pre[i]][i]);

                }

            break;

        }

    }while(i<=n);

    for(int i=2;i<=n;i++)//把不是剩下的入邊都加上

        if(!ced[i])ans+=gra[pre[i]][i];

    return ans;

}



void re(void)

{

	cin>>rep>>del;

	for(int i=0;i<26;i++)cin>>val[i];

	cin>>n;n++;

	for(int i=2;i<=n;i++)

        cin>>s[i];

}



void run(void)

{

	for(int i=2;i<=n;i++)

        for(int j=2;j<=n;j++)

            gra[i][j]=inf;

    for(int i=2;i<=n;i++)

        for(int j=2;j<=n;j++)

            if(i!=j)

                dpt(i,j);

    for(int i=2;i<=n;i++)

    {

        int a=0,len=s[i].size();

        for(int j=0;j<len;j++)a+=val[s[i][j]-'a'];

        gra[1][i]=a;

    }

    cout<<ZHULIU()<<endl;

}



int main()

{

    //freopen("d:\\in.txt","r",stdin);

	int ncase;

	scanf("%d",&ncase);

	for(int i=1;i<=ncase;i++)

	{

		re();

		cout<<"Case #"<<i<<": ";

		run();

	}

	return 0;

}


      

UESTC1565 Smart Typist


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 一本大道久久a久久综合 | 五月天久久婷婷 | 亚洲激情视频 | 91九九| 久久国产a| 特级毛片www欧美 | 欧洲一区在线观看 | 亚洲精品98久久久久久中文字幕 | 色婷婷亚洲 | 精品久久网站 | 天天看片夜夜爽 | 婷婷综合另类小说色区 | 成年女人毛片 | 亚洲99久久久久综合 | 四虎影视永久费观看在线 | 久久综合久久久久 | 一级日本强免费 | 草草在线观看 | 九九久久99 | 天天做天天爱夜夜大爽完整 | 免费超级淫片日本高清视频 | 久久久中文字幕日本 | 国产高清精品久久久久久久 | 女人的毛片| 亚洲欧美另类图片 | 精品久久久久久免费影院 | 四虎最新网址在线观看 | 99成人国产精品视频 | 亚洲综合图区 | 久久精品一区 | 理论片 我不卡影院 | 一级黄色录像视频 | 久久夜色精品国产欧美 | 久久99国产亚洲高清观看首页 | 青青草国产免费一区二区 | 青草青视频在线观看 | 99中文字幕 | 日本在线观看一级高清片 | 亚洲精品一区二区三区四区手机版 | 亚洲精品99久久久久中文字幕 | 伊人网址 |