CDOJ 1349 柱爷大战滑稽王(dp LCS转LIS)

来源:互联网 发布:php简易查询系统源码 编辑:程序博客网 时间:2024/06/07 08:22

H - 柱爷大战滑稽王

Time Limit: 4500/4500MS (Java/Others)     Memory Limit: 120000/120000KB (Java/Others)
 

咸鱼历772002772002年,咸鱼王的军队趁着世界屏障力量达到最低谷时,强行撕裂了空间来到了我们的世界

瞄哈哈村则首当其冲!,形势不容乐观

据传,咸鱼王所在的世界有三大尊者,分别是

咸鱼王title

滑稽王title

挠头王title

三个人的实力深不可测,其中以咸鱼王实力最强,因而三人隐隐以咸鱼王为首

阵前

“瞄哈哈村的鼠辈,可有人敢出来与我一战?!”

“滑稽王又来叫阵了!,欺我瞄哈哈村无人吗?”,卿学姐愤怒的说道,话虽如此,瞄哈哈村阵前的气氛却静的可怕,每个人看向滑稽王的眼神中都充满了忌惮之色,竟无一人敢应战.

“据传滑稽王的吃惊诀已经修炼到了大成,其幻化出的吃惊光剑攻击力惊人,与其正面对决,怕是....”,天行廖(狗头军师)在一旁分析到.

在一旁原本静坐的柱爷突然睁开双眼,眼中爆发出惊人光芒

“我可一战,定取滑稽王首级”

诸将易得耳。至如柱者,国士无双

为了简化滑稽王和柱爷的对决,我们将柱爷和滑稽王数据化得到

柱爷的咸鱼神功有NN个招式,每个招式可以造成AiAi点伤害

滑稽王的吃惊诀有MM个招式,每个招式可以造成BiBi点伤害

柱爷为了给滑稽王一个下马威,决定在一瞬间打出这NN个招式,这NN个招式可以造成[AB][A数组,B数组的最长公共子序列长度]+1的额外伤害

柱爷现在想知道能够造成多少点额外伤害?

Input

第一行两个整数NMN,M,分别表示咸鱼神功,吃惊诀的招式数目

接下来一行,NN个整数AiAi,分别表示咸鱼神功第ii个招式的伤害

接下来一行,MM个整数BiBi,分别表示吃惊诀第ii个招式的伤害

数据保证:

  • 1NM1061≤N,M≤106

  • |AiBi|109|Ai,Bi|≤109

  • AiAi互不相同

Output

输出仅一行,表示柱爷能够造成的额外伤害

Sample input and output

Sample InputSample Output
4 41 2 3 41 2 3 4
5
3 31 2 33 2 1
2
3 31 2 34 5 6
1

Hint

最长公共子序列(LCS):不一定要连续!

测试数据没有样例



题解:这题看上去只是要求一个最大公共子序列,但是,显然使用传统的LCS是会MLE的,因此,这里使用LCS转LIS的方法,然后求解

代码如下:

#include <iostream>#include <stdio.h>#include <vector>#include <algorithm>#include <map>using namespace std;#define LEN 10000005int f[LEN], b[LEN],d[LEN],lin[LEN];int M,N;map <int,int> maplis;vector <int> aa;map<int,int>::iterator it;int bsearch(const int *f, int size, const int &a){    int l=0, r=size-1;    while( l <= r )    {        int mid = (l+r)/2;        if( a > f[mid-1] && a <= f[mid] ) return mid; // >&&<= 换为: >= && <        else if( a < f[mid] ) r = mid-1;        else l = mid+1;    }}int LIS(const int *a, const int &n){     if(aa.empty())        return 0;     int i, j, size = 1;     f[0] = a[0]; d[0] = 1;     for( i=1; i < n; ++i ){          if( a[i] <= f[0] ) j = 0;                 // <= 换为: <         else if( a[i] > f[size-1] ) j = size++;   // > 换为: >=         else j = bsearch(f, size, a[i]);         f[j] = a[i]; d[i] = j+1;     }     return size;}int main(){    int i,m;    scanf("%d %d", &M,&N);    for(i = 1; i <= M; i++)    {        scanf("%d",&m);        maplis.insert(map<int,int>::value_type(m,i));    }    for(i = 1; i <= N; i++)        scanf("%d", &b[i]);    for(i = 1; i <= N; i++)    {        it= maplis.find(b[i]);        if(it!=maplis.end())            aa.push_back(maplis[b[i]]);    }    for(i=0;i<aa.size();i++)        lin[i]=aa[i];    printf("%d",LIS(lin,i)+1);return 0;}


0 0
原创粉丝点击