链接:8.3比赛

这次是动态规划里的LCS,LIS,LCIS专场.......

A.Common Subsequence

就是:给出两个字符串,求出其中的最长公共子序列的长度~LCS

代码:

 //memory:4276KB  time:109ms
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std; int c[][]; int maxx(int a,int b,int c)
{
if(b>a) a=b;
if(c>a) a=c;
return a;
} int LCS_Lenght(string x,string y)
{
int m=x.length();
int n=y.length();
int i,j,v1,v2,v3;
memset(c,,sizeof(c));
for(i=;i<=m;i++)
for(j=;j<=n;j++)
{
v3=c[i-][j-];
if(x[i-]==y[j-]) v3=v3+;
v2=c[i-][j];
v1=c[i][j-];
c[i][j]=maxx(v1,v2,v3);
}
return c[m][n];
} int main()
{
string x,y;
while(cin>>x>>y)
{
int p=LCS_Lenght(x,y);
cout<<p<<endl;
}
return ;
}

B.Palindrome

题意:给出一个字符串,求出它的最长上升子序列~LIS

如果表格直接用5001x5001的会超内存(在POJ上的内存开的很大,代码能过),因此就要进行优化......因为在表格上走的每一步只与与它左侧、上侧,左斜上侧的三个点有关,每一排的点只与上一排的点有关,因此在不要求回溯求出要求点的值时,可以只用2x5001的表格即可~

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std; int c[][],k; int maxx(int a,int b,int c)
{
if(b>a) a=b;
if(c>a) a=c;
return a;
} int LCS_Lenght(string x)
{
int i,j,v1,v2,v3;
memset(c,,sizeof(c));
for(i=;i<=k;i++)
for(j=;j<=k;j++)
{
v3=c[(i-)%][j-]; //对二取余是重点~
if(x[i-]==x[k-j]) v3=v3+;
v2=c[(i-)%][j];
v1=c[i%][j-];
c[i%][j]=maxx(v1,v2,v3);
}
return c[k%][k];
} int main()
{
string x;
while(cin>>k)
{
cin>>x;
int p=LCS_Lenght(x);
cout<<k-p<<endl;
}
return ;
}

//memory:344KB  time:687ms

C.魔法串

给出两个字符串a和b,并给出一些转换关系,看b是否能通过这些转换关系和删除字符得到a~

代码:

//打出一个转换表,看b中的字符是否能通过转换关系与a中的字符相等~

 #include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std; const int N = ; int main()
{
int cas,t;
scanf("%d",&t);
for(cas = ; cas<=t; cas++)
{
getchar();
char s1[N],s2[N];
int len1,len2;
gets(s1);
gets(s2);
len1 = strlen(s1);
len2 = strlen(s2);
int n,i,j;
int change[][] = {};
scanf("%d",&n);
for(i = ; i<n; i++)
{
char a,b;
getchar();
scanf("%c %c",&a,&b);
change[a-'a'][b-'a'] = ;//打下一个转换表
}
j = ;
int flag = ;
for(i = ; i<len1; i++)
{
if(j == len2)
break;
if(s1[i] == s2[j]) //相等继续
{
j++;
continue;
}
while(s2[j]!=s1[i])
{
if(j==len2)
{
flag = ;
break;
}
if(change[s2[j]-'a'][s1[i]-'a'] == )
{
j++;
break;
}
else
j++;
}
}
printf("Case #%d: ",cas);
if(!flag)
printf("happy\n");
else
printf("unhappy\n");
}
return ;
}

//memory:232KB  time:0ms

代码来自:http://blog.csdn.net/libin56842/article/details/8960511

方法二:

找最长公共子序列(LCS),在对应关系中略有改动~

代码:

 #include<iostream>
#include<string>
#include<cstring>
using namespace std;
int dp[][];
bool has[][];
int maxi(int x,int y)
{
if(x>y)
return x;
else return y;
}
int main()
{
int i,j,t,m,count=,len1,len2;
char a,b;
string str1,str2;
cin>>t;
while(t--)
{
count=count+; cin>>str1>>str2;
len1=str1.length();
len2=str2.length();
memset(dp,,sizeof(dp));
memset(has,,sizeof(has));
cin>>m;
for(j=;j<=m;j++)
{
cin>>a>>b;
has[a][b]=; //记录对应关系~
}
cout<<"Case #"<<count<<": ";
for(i=;i<=len1;i++)
for(j=;j<=len2;j++)
{
if(str1[i-]==str2[j-]||has[str2[j-]][str1[i-]]==) //has[][]是看通过对应关系能否相等~
dp[i][j]=dp[i-][j-]+;
else dp[i][j]=maxi(dp[i-][j],dp[i][j-]);
} if(dp[len1][len2]==len1)
cout<<"happy"<<endl;
else cout<<"unhappy"<<endl;
}
return ;
}

//memory:4264KB  time:78ms

D.最少拦截系统

贪心算法:

找了段便于理解的解释就直接贴出来了。对于这个题目的测试例的解释:当8枚导弹依次飞来时,对于前三枚导弹(300,207,155),用第一套系统即可拦截,每一次更新记录,即:对第一枚导弹直接拦截,第二枚导弹来临时也用第一套系统拦截,记录改变成207,当用第一套系统拦截第三枚后记录修改为155,当第四枚导弹来时按照系统规定,第一套系统无法实现对第四枚导弹的拦截任务,因此,开第二套系统,为了使用最少系统,必须对以后的每一枚导弹贪心,即:拿这枚导弹和以前的导弹最小记录依次做比较,寻找一个和这枚导弹高度最接近的记录并用这枚导弹的高度替换原记录,最后记录数组中的个数就是最少需要的系统数。

代码:

#include<stdio.h>
#include<math.h>
int a[],b[];
int main()
{
int n,i,j,k;
while(scanf("%d",&n)!=EOF)
{
b[]=;k=;
for(i=;i<n;i++)
{
scanf("%d",&a[i]);
for(j=;j<=k;j++)
{
if(a[i]<b[j])
{
b[j]=a[i];
break;
}
else if(j==k)
{
k++;
b[k]=a[i];
break;
}
}
}
printf("%d\n",k);
}
return ;
}

//memory:240KB   time:15ms

动态规划:

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; int main()
{
int t,a[],dp[],i,j,max;
while(scanf("%d",&t)!=EOF)
{
for(i=;i<=t;i++)
scanf("%d",&a[i]);
memset(dp,,sizeof(dp));
max=-;
for(i=;i<=t;i++)
for(j=i-;j>=;j--)
if(a[i]>a[j] && dp[i]<dp[j]+) //如果拦截中出现了非单调递减的高度~拦截系统就加1~
dp[i]=dp[j]+;
for(i=;i<=t;i++)
if(max<dp[i]) max=dp[i];
printf("%d\n",max);
}
return ;
}

//memory:232KB  time:15ms

方法三:

通过对E题的思考,突然发现其实D题的本质与E题相同,同样可以用E题的方法一解出来~然后经过与同学的讨论......额~无论是求最长上升子序列还是最长下降子序列都可以用此方法(略微做一点变形)做出来~~~

代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; class Dolls
{
public:
int x,id;
}D[]; int main()
{
int n;
while(~scanf("%d",&n))
{
int i,minn;
memset(D,,sizeof(D));
for(i=;i<n;i++)
scanf("%d",&D[i].x);
int number=,j;
for(i=;i<n;i++)
if(D[i].id==)
{
minn=D[i].x;
number++;
for(j=i+;j<n;j++)
if(D[j].x<minn && D[j].id==)
{
D[j].id=;
minn=D[j].x;
}
}
printf("%d\n",number);
}
return ;
}

E.Nested Dolls

题意:有一堆俄罗斯套娃,把这些套娃全部套好,看最后会剩多少套娃~

方法一:

把所有套娃都按x(宽度)从大到小排好序【注:当宽度相等的时候,y(高度)小的排在前】,然后从第一个套娃开始看排在后的套娃能放进多少,能放进的都进行标记,并更新minn(能放进套娃的最大高度);再找下一个未标记的套娃,重复操作,......直到没有未标记的套娃为止~操作了都少次,就剩下多少套娃~

代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; class Dolls
{
public:
int x,y,id;
}D[]; bool comp(Dolls a,Dolls b) //对套娃进行排序
{
if(a.x==b.x) return a.y<b.y;
return a.x>b.x;
} int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
int i,minn;
scanf("%d",&n);
memset(D,,sizeof(D));
for(i=;i<n;i++)
scanf("%d%d",&D[i].x,&D[i].y);
sort(D,D+n,comp);
int number=,j;
for(i=;i<n;i++)
if(D[i].id==) //找到未标记的套娃(即作为容器的最大套娃)
{
minn=D[i].y;
number++;
for(j=i+;j<n;j++)
if(D[j].y<minn && D[j].id==) //判断是否能够放进这个套娃
{
D[j].id=; //能放进进行标记
minn=D[j].y; //更新能放进套娃的最大高度
}
}
printf("%d\n",number);
}
return ;
}

//memory: 464KB  time: 468ms

F.Greatest Common Increasing Subsequence

题意:看题目就知道,是求最长公共上升子序列~~~~

//题目有个略坑的地方,输出要空一行,最后一个输出又不要空.........不这样的话会PE......= =

代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; int main()
{
long t,n,m,a[],b[],len[],i,j,k,maxx;
scanf("%ld",&t);
while(t--)
{
scanf("%ld",&n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
scanf("%ld",&m);
for(i=;i<=m;i++)
scanf("%ld",&b[i]);
memset(len,,sizeof(len));
for(i=;i<=n;i++)
{
k=;
for(j=;j<=m;j++)
{
if(a[i]>b[j] && len[j]>len[k]) //len[j]代表的是b[j]处,得到的最长公共上升子序列的长度
k=j; //len[k]代表的是在a[i]>b[j]时,所有的上升子序列中最长的一个~
if(a[i]==b[j])
len[j]=len[k]+;
}
}
for(i=,maxx=;i<=m;i++)
if(len[i]>maxx) maxx=len[i]; //找出最长公共上升子序列的长度~~
printf("%ld\n",maxx);
if(t) printf("\n");
}
return ;
}

//memory:228KB  time:0ms

G.吉哥系列故事――完美队形I

与F题其实很相似,代码原理上是相同的,只是略有改动~

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std; int main()
{
int t,n,a[],b[];
scanf("%d",&t);
while(t--)
{
int mxx,number=,i,j;
scanf("%d",&n);
memset(a,,sizeof(a));
for(i=;i<n;i++)
scanf("%d",&a[i]);
memset(b,,sizeof(b));
for(i=n-;i>=;i--)
{
mxx=;
for(j=;j<=i;j++)
{
if(a[j]<a[i])
mxx=mxx>b[j]?mxx:b[j]; //mxx代表在a[j]<a[i]时最大的上升子序列的对数
else
if(a[j]==a[i])
b[j]=mxx+;
if(j<i && number<*b[j]) number=*b[j];
else
number=number>*b[j]-?number:*b[j]-;
}
}
printf("%d\n",number);
}
return ;
}

//memory:228KB  time:0ms

8-3-COMPETITION的更多相关文章

  1. A Regularized Competition Model for Question Diffi culty Estimation in Community Question Answering Services-20160520

    1.Information publication:EMNLP 2014 author:Jing Liu(在前一篇sigir基础上,拓展模型的论文) 2.What 衡量CQA中问题的困难程度,提出从两 ...

  2. CIFAR-10 Competition Winners: Interviews with Dr. Ben Graham, Phil Culliton, & Zygmunt Zając

    CIFAR-10 Competition Winners: Interviews with Dr. Ben Graham, Phil Culliton, & Zygmunt Zając Dr. ...

  3. Kaggle Competition Past Solutions

    Kaggle Competition Past Solutions We learn more from code, and from great code. Not necessarily alwa ...

  4. UESTC_The Most Wonderful Competition CDOJ 56

    The Most Wonderful Competition Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB ...

  5. codeforces 883M. Quadcopter Competition 思路

    M. Quadcopter Competition time limit per test 3 seconds memory limit per test 256 megabytes input st ...

  6. Codeforces 1082C Multi-Subject Competition(前缀+思维)

    题目链接:Multi-Subject Competition 题意:给定n名选手,每名选手都有唯一选择的科目si和对应的能力水平.并且给定科目数量为m.求选定若干个科目,并且每个科目参与选手数量相同的 ...

  7. HGOI 20190407 Typing Competition Round #1 出题记

    /* ljc20020730出的HGOI20190407的模拟赛. 考试结果比预期难的不少,可能是由于本来计划5h的比赛打了4h吧. 就当普及组模拟赛好了... 难度大概4紫吧(弱省省选难度) 出境 ...

  8. 2009 Putnam Competition B3

    2009 Putnam Competition B3 题目大意: \(T(t\le10^5)\)次询问,每次询问\(n(n\le2\times10^6)\)以内的正整数构成的集合,有多少满足若\(a\ ...

  9. Codeforces 1082C Multi-Subject Competition 前缀和 A

    Codeforces 1082C Multi-Subject Competition https://vjudge.net/problem/CodeForces-1082C 题目: A multi-s ...

  10. HDU 6095 17多校5 Rikka with Competition(思维简单题)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

随机推荐

  1. Linux文件3个时间点(access time,modify time,change time)

    在Linux中使用stat命令来查看文件的详细信息. 如图所示,会出现3个类型的时间,分别是Access,Modify,Change. access time:表示最后一次访问(仅仅是访问,没有改动) ...

  2. Asp.Net MVC 使用FileResult导出Excel数据文件

    MVC实现Excel导出功能,今天来记录一下. 采取了最简单的方法.(转载)   用的是Html拼接成Table表格的方式,返回 FileResult 输出一个二进制的文件. 第一种:使用FileCo ...

  3. 关于Java(JDBC介绍)

    JDBC API 允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的. JDBC 简单功能 连接数据源,如数据库 传给数据库查询和更新指令 获取并处理数据库返回结果(对查询等的响应) 示例代码 ...

  4. int 占一个机器字长

    int与short int是不一样的. C++标准规定,int占一个机器字长.在32位系统中int占32位,也就是4个字节, 而在老式的16位系统中,int占16位,即2个字节. 而C++标准中只限制 ...

  5. Java 8 的 JVM 有多快?Fork-Join 性能基准测试

    Java 8 已经发布一段时间了,许多开发者已经开始使用 Java 8.本文也将讨论最新发布在 JDK 中的并发功能更新.事实上,JDK 中已经有多处java.util.concurrent 改动,但 ...

  6. 【网络流24题】No. 20 深海机器人问题 (费用流)

    [题意] 深海资源考察探险队的潜艇将到达深海的海底进行科学考察.潜艇内有多个深海机器人. 潜艇到达深海海底后, 深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本. 沿 ...

  7. Android用户界面UI组件--AdapterView及其子类(四) GridView

    GridView常用的XML属性: android:columnWidth  设置列的宽度. android:horizontalSpacing  两列之间的间距.  android:numColum ...

  8. 【HDOJ】3127 WHUgirls

    #include <stdio.h> #include <string.h> #define mymax(a, b) (a>b) ? a:b typedef struct ...

  9. C++ Prime:指针和const

    与引用一样,也可以令指针指向常量或非常量,类似于常量引用,指向常量的指针不能用于改变其所指对象的值.要想存放常量对象的地址,只能使用指向常量的指针: const double pi = 3.14; / ...

  10. oracle core04_undo

    undo信息 oracle中undo的信息主要完成下面的功能: 1,构建块一致性读 2,回滚事务 UBA:undo block address 1,块中的事务槽ITL中的UBA表示这个ITL所在的bl ...