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
一个整数,表示最大的分数和。
9
6 3 7 4 2 A K R T
3 5 4 7 R A Q K T
140
Data Limit
10≤n≤2000
Problem Source
hackerrank
-
分析:
- 最早想到的是搜索,但一看n的范围。。。(⊙o⊙)…
所以,DP在所难免! - 用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! - 这样,只需要两重循环,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——题解的主要内容,如果未能解决你的问题,请参考以下文章