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

UESTC1565 Smart Typist

系統 1855 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條評論
主站蜘蛛池模板: sihu永久在线播放地址 | 青青青免费高清视频在线 | 亚洲精品久久久久中文字小说 | 福利视频网站 | 国产精品一区二区三区久久 | 国产精品短视频 | 午夜毛片福利 | 四虎影院在线免费观看 | 国产成人精品日本亚洲麻豆 | 久久精品国产亚洲综合色 | 欧美三级一区二区 | 亚洲国产精品婷婷久久 | 手机看片日韩国产 | 国产精品网页 | 日韩欧美在线一级一中文字暮 | 亚洲国产二区三区久久 | 日韩免费视频一区二区 | 26uuu久久 | 色综合久久综合欧美综合 | 九九九热在线精品免费全部 | 97se色综合一区二区二区 | 成人黄色免费网站 | 国产成人福利夜色影视 | 国产久草视频 | 成人爽a毛片在线视频网站 成人爽视频 | 在线视频 国产交换 | 不卡的在线视频免费观看 | 波多野结衣av1区2区3区 | 天天干天天干天天插 | 久久久久久久久国产 | 全黄一级裸片视频在线观看 | 久久久一级| 亚洲人人干 | 亚洲国产精品乱码在线观看97 | 国产未成女年一区二区 | 草的爽免费视频 | 91欧美在线视频 | 妖精视频免费在线观看 | 亚洲免费一区 | 黄页网址大全免费观看美女 | 亚洲欧美日韩综合在线 |