问题A - 签到题
问题描述
题目分析
这是一个比较简单的,算数题,每次变化只能够有2或者3次,我就直接建立了一个循环,直接遍历求解。每次操作除2,除3即可。直到最后没法再除,即可。
代码
#include<iostream>
using namespace std;
long long n,m;
int main()
{
scanf("%lld%lld",&n,&m);
if(n>m||m%n!=0)
{
cout<<"-1"<<endl;
return 0;
}
int step=0;
while(n<m)
{
if(m%(n*2)==0)
{
n=n*2;
step++;
}
else if(m%(n*3)==0)
{
n=n*3;
step++;
}
else
{
break;
}
}
if(m==n)
cout<<step<<endl;
else
cout<<"-1"<<endl;
return 0;
}
问题 B - LIS & LCS
问题描述
题目分析
LIS是最长上升子序列,LCS是最长公共子序列。LIS就是在一串数组中挑出其中的某些数字,按顺序排放,其组成的子序列仍然是严格单调增加的,就是LIS序列。LCS是指两个数组从中按顺序抽部分数字,能组成一样的数组。
首先是计算LIS,这个我的计算方法采用的是两个for循环,用dis数组储存这个数到之前能够选择最长的LIS的长度,每次计算每个比这个数小并排在前面的其他数的dis+1,存取当中最大的一个数。然后在找dis里最大的数字,即是我们要求得LIS,其时间复杂度为n^2,
LCS,也是两个for循环,将A数组与B数组一个个进行比较,如果相等就是dis数组中的前一个数的值+1,如果不等,就比较,挑选前一个数(i-1)和(j-1)中比较大的那一个。dis存放的就是遍历数组得到前面的数字中能够组成一样序列的数字个数。复杂度nm
代码
#include<iostream>
#include<cmath>
using namespace std;
int m,n;
int A[5010],B[5010];
int ans1=1;
int dis[5010];
int dis2[5010][5010];
int main()
{
cin>>n>>m;
for(int n1=1;n1<=n;n1++)
{
cin>>A[n1];
}
for(int m1=1;m1<=m;m1++)
{
cin>>B[m1];
}
//LIS
dis[1]=1;
for(int i=2;i<=n;i++)
{
dis[i]=1;
int aa=1000000;
for(int j=i-1;j>0;j--)
{
if(A[j]<A[i])
{
dis[i]=max(dis[j]+1,dis[i]);
//cout<<"i="<<i<<" j="<<j<<endl;
//cout<<"shu="<<A[i]<<" shu2="<<A[j]<<" dis="<<dis[i]<<endl;
//j=0;//出循环
}
}
if(dis[i]>dis[ans1])
ans1=i;
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
dis2[i][j]=0;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(A[i]==B[j])
dis2[i][j]=dis2[i-1][j-1]+1;
else
dis2[i][j]=max(dis2[i-1][j],dis2[i][j-1]);
}
}
cout<<dis[ans1]<<" "<<dis2[n][m]<<endl;
return 0;
}
遇到的问题
对于LCS的dis数组处理不是很熟悉,知道是按照顺序进行下去,但是其怎样传递下去这个消息并没有在一开始就弄明白
问题C - 拿数问题 II
问题描述
题目分析
这个题目就比较简单,先是将输入的数据转变一下,把n个数转变成a[i]表示值为i的数有多少个,然后再分析这个数拿还是不拿的一个问题,如果拿,就是上一个数不拿的,情况的大小加上这个数拿的情况的大小。如果不拿,就是比较上一个数拿和不拿哪一个大,选哪个。复杂度m(a的最大值)
代码
#include<iostream>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
int n;
int shu;
int mm;
long long mm1;
long long a[100005];
long long dis[100005][2];
int main()
{
cin>>n;
mm=0;
mm1=0;
memset(dis,0,sizeof(dis));
memset(a,0,sizeof(a));
for(int n1=0;n1<n;n1++)
{
cin>>shu;
a[shu]++;
if(shu>mm)
mm=shu;
}
for(long long i=1;i<=mm;i++)
{
dis[i][0]=max(dis[i-1][1],dis[i-1][0]);//不选
dis[i][1]=dis[i-1][0]+i*a[i];
mm1=max(dis[i][0],mm1);
mm1=max(dis[i][1],mm1);
}
cout<<mm1<<endl;
}