• 某科学的打麻将(最大匹配序列+模拟)


    某科学的打麻将
    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 113 Accepted Submission(s): 33

    Problem Description
    过年打麻将果然是一项必备技能(雾),打麻将的起手式是整理好自己手中的牌,现在你有十三张牌(只可能出现一万到九万,一筒到九筒,一条到九条),你要把这些牌整理好,使得相同花色的牌必须在连续的唯一一段(即所有的"万"要放在一起,所有的"条"要放在一起,所有的"筒"要放在一起。),每段内牌是按照从小到大的顺序排列(“万”,“条”,“筒”的顺序没有要求)。你每次只能将当前牌中的任意一张牌放到最左边或者最右边。请问最少经过多少次可以使得牌被整理好。
    一万到九万,用数字1-9表示
    一筒到九筒,用小写字母a-i表示
    一条到九条,用大写字母A-I 表示

    Input
    第一行 一个数字T代表数据组数(T<=10000)
    接下来每行 13个字符 代表初始的牌

    Output
    T行每行一个数字,代表答案

    Sample Input

    1
    3abcABBDEFG11

    Sample Output

    1
    Hint

    样例解释
    我们把3 放到 最右边就好了
    abcABBDEFG113

    题意

    分析

    可以知道最后情况只有6种,那么就是找到初始串与最终串的最大匹配序列,如
    (bac1231BDEABB)(abc1123ABBBDE)最大匹配序列为(ac123ABB),令dp[i][j]代表前i个初始串字符与前j个最终串字符的最大匹配序列的长度,那么

    [dp[i][j]=(s[i]==f[j])?dp[i-1][j-1]:dp[i-1][j] ]

    每次更新匹配长度ans,最后答案为13-ans

    trick

    代码

    #include <bits/stdc++.h>
    #include <cstring>
    using namespace std;
    
    #define ll long long
    #define F(i,a,b) for(int i=a;i<=b;++i)
    #define R(i,a,b) for(int i=a;i<b;++i)
    #define mem(a,b) memset(a,b,sizeof(a))
    //#pragma comment(linker, "/STACK:102400000,102400000")
    //inline void read(int &x){x=0; char ch=getchar();while(ch<'0') ch=getchar();while(ch>='0'){x=x*10+ch-48; ch=getchar();}}
    
    int t;
    int cnt1,cnt2,cnt3,ans;
    char s[20],f[20],a[14],b[14],c[14];
    int dp[20][20];
    vector<char>v[3];
    void work()
    {
    	mem(dp,0);
    	//printf("%s ",f);
    	for(int i=0;i<13;++i)
    		for(int j=0;j<13;++j)
    		{
    			if(s[i]==f[j])
    			{
    				if(i==0||j==0) dp[i][j]=1;else dp[i][j]=dp[i-1][j-1]+1;
    			}
    			else
    			{
    				if(i==0) dp[i][j]=0;
    				else dp[i][j]=dp[i-1][j];
    			}
    			ans=max(ans,dp[i][j]);
    		}
    	//printf("dp[n][m]=%d
    ",dp[cnt][cnt]);
    }
    int main()
    {
        for(scanf("%d",&t);t--;)
        {
        	scanf("%s",s);
        	mem(a,0);mem(b,0);mem(c,0);
        	cnt1=cnt2=cnt3=0;
        	for(int i=0;s[i]!='';++i)
        	{
        		if(s[i]<='z'&&s[i]>='a') a[cnt1++]=s[i];
        		else if(s[i]<='Z'&&s[i]>='A') b[cnt2++]=s[i];
        		else c[cnt3++]=s[i];
        	}
        	ans=0;
        	sort(a,a+cnt1);sort(b,b+cnt2);sort(c,c+cnt3);
        	mem(f,0);strcat(f,a);strcat(f,b);strcat(f,c);work();
        	mem(f,0);strcat(f,a);strcat(f,c);strcat(f,b);work();
        	mem(f,0);strcat(f,b);strcat(f,a);strcat(f,c);work();
        	mem(f,0);strcat(f,b);strcat(f,c);strcat(f,a);work();
        	mem(f,0);strcat(f,c);strcat(f,a);strcat(f,b);work();
        	mem(f,0);strcat(f,c);strcat(f,b);strcat(f,a);work();
        	printf("%d
    ",13-ans );
        }
        return 0;
    }
    
  • 相关阅读:
    整合Sleuth
    idea springboot 微服务批量启动
    思维的八层境界(深度好文)
    【格局视野】三色需求与工作层次
    【阅读推荐】改变你思维模式的书单
    【软件架构】七款代码味道识别工具
    【软件架构】代码重构之道
    【Android】EventBus 源码解析
    【软件架构】IM架构设计(安卓版)
    【设计模式】Java版设计模式的类图汇总
  • 原文地址:https://www.cnblogs.com/chendl111/p/7125523.html
Copyright © 2020-2023  润新知