Kabloom——题解

Posted yuyer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kabloom——题解相关的知识,希望对你有一定的参考价值。

  • 题目:

Problem

给定两叠各有n张的扑克牌,牌的种类有A,2,3,4,5,6,7,8,9,T,J,Q,K,R,其中A表示Aces,2到10为数字牌,其中10用字母T表示,J,Q,K为花牌,R表示王。
你可以再两叠牌中各去掉若干张牌,但不能改变牌之间的相对顺序。若两叠牌的对应位置上的纸牌相同,则构成一对,并获得相应的分数。
A的分数是20,花牌的分数是15,数字牌的分数为数字的大小。王牌可以被用作任意牌派对,其分数由与派对的牌的决定,
如一个王和一个A配对分数为20,和花牌派对的分数为15,和数字牌派对的分数为数字的大小。特殊的,两个王派对的分数为50。

请计算最大分数和。注意,一对牌的分数是牌的分数的两倍,比如一对A的分数是20×2=40

Input Data

第一行,一个整数n。
第二行,n个字符,表示第一叠纸牌。
第三行,n个字符,表示第二叠纸牌。

Output Data

一个整数,表示最大的分数和。

 Input / Output Sample
9
6 3 7 4 2 A K R T
3 5 4 7 R A Q K T
140

Data Limit

10n2000

Problem Source

hackerrank

  • 分析:

  1. 最早想到的是搜索,但一看n的范围。。。(⊙o⊙)…
    所以,DP在所难免!
  2. 用DP就得分析状态的转移:
     首先分析数组f[i][j]所代表的含义。这里定义:表示做到第一叠牌的第i张,第二叠牌的第j张时的最大得分。
     其次,分析f[i][j]可以由三个状态转移而来:
            1、f[i-1][j]:略过第一副牌的这张牌,直接取上一次的分数(你可以再两叠牌中各去掉若干张牌)。
            2、f[i][j-1]:略过第二副牌的这张牌。
            3、f[i-1][j-1]+得分:两张牌都不略过(就是要配对得分),但需要一个前提:两张牌相等或者有一个为王(可以转换)。满足这个条件,就可以进行第三              次的比较。同时,为了方便,写一个函数score来计算每次的得分,该函数根据题目编写,详见代码注释。
    最后,f[n][n]就是在第一叠牌第n张,第二叠牌第n张时,得到的最大值了。但注意,题目要求*2!
  3. 这样,只需要两重循环,n方的时间复杂度,2000的平方就可以过了。
  • 代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=2000+5;
 4 int score(char x,char y)
 5 {
 6     if(x==R && y==R) return 50;//两个王,不用想。
 7     //注意,两个王的情况必须先处理,否则会进入if而没有输出!
 8     if(x==R)
 9     {
10         if(y==A) return 20;//可以根据另个数进行变化
11         if(y==Q || y==K || y==J) return 15;
12         if(y==T) return 10;
13         return y-0;//不是字母,就是数字了。
14     }
15     if(y==R)//y同x一样
16     {
17         if(x==A) return 20;
18         if(x==Q || x==K || x==J) return 15;
19         if(x==T) return 10;
20         return x-0;
21     }
22     //所有王的情况都不是,剩下的肯定是两个相同的、不是王的情况。
23     if(x==A) return 20;
24     if(x==Q || x==K || x==J) return 15;
25     if(x==T) return 10;
26     return x-0;//和上面一样
27 }
28 char a[MAXN],b[MAXN];
29 int n,f[MAXN][MAXN];
30 int main()
31 {
32     cin>>n;
33     for(int i=1;i<=n;i++) 
34     cin>>a[i];
35     for(int i=1;i<=n;i++)
36     cin>>b[i];
37     //2000数据,不算特别大,暂且用个cin
38     for(int i=1;i<=n;i++)
39     for(int j=1;j<=n;j++)
40     {
41         f[i][j]=max(f[i-1][j],f[i][j-1]);
42         if(a[i]==b[j] || a[i]==R || b[j]==R)
43         f[i][j]=max(f[i][j],f[i-1][j-1]+score(a[i],b[j]));
44     }
45     printf("%d
",f[n][n]*2);
46     return 0;
47 }    

 

以上是关于Kabloom——题解的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序代码片段

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器