A - 签到题
问题描述
东东在玩游戏“Game23”。在一开始他有一个数字n,他的目标是把它转换成m,在每一步操作中,他可以将n乘以2或乘以3,他可以进行任意次操作。输出将n转换成m的操作次数,如果转换不了输出-1。
Input
输入的唯一一行包括两个整数n和m(1<=n<=m<=5*10^8).
Output
输出从n转换到m的操作次数,否则输出-1.
思路
m/n之后直接while /2/3 之后判断一下。
代码
#include<iostream>
using namespace std;
int main()
{
int x,y,ans;
cin>>x>>y;
if (y%x!=0)
{
cout<<-1<<endl;
return 0;
}
x=y/x;
ans=0;
while (x%3==0)
{
x=x/3;
ans++;
}
while (x%2==0)
{
x=x/2;
ans++;
}
if (x==1)
cout<<ans<<endl;
else
cout<<-1<<endl;
return 0;
}
B - LIS & LCS
问题描述
给定两个序列A和B。
求序列A的LIS和序列AB的LCS的长度。
注意,LIS为严格递增的,即a1<a2<…<ak(ai<=1,000,000,000)。
Input
第一行两个数n,m(1<=n<=5,000,1<=m<=5,000)
第二行n个数,表示序列A
第三行m个数,表示序列B
Output
输出一行数据ans1和ans2,分别代表序列A的LIS和序列AB的LCS的长度
思路
f[i]存储从1到当前的LIS长度,f[i]=max(f[i],f[j]+1)。
ff[i][j]存储序列A[1…i]和序列B[1…j]的LCS,
ff[i][j]=max(ff[i-1][j],ff[i][j-1]);
if (a[i]==b[j])
ff[i][j]=max(ff[i][j],ff[i-1][j-1]+1);
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[10010],b[10010],f[10010];
int ff[5050][5050];
int main()
{
int n,m,ans=0;
cin>>n>>m;
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
for (int i=1;i<=m;i++)
scanf("%d",&b[i]);
for (int i=1;i<=n;i++)
f[i]=1;
for (int i=1;i<=n;i++)
for (int j=1;j<i;j++)
if (a[i]>a[j])
f[i]=max(f[i],f[j]+1);
for (int i=1;i<=n;i++)
ans=max(f[i],ans);
ff[0][0]=ff[0][1]=ff[1][0]=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
ff[i][j]=max(ff[i-1][j],ff[i][j-1]);
if (a[i]==b[j])
ff[i][j]=max(ff[i][j],ff[i-1][j-1]+1);
}
cout<<ans<<" "<<ff[n][m]<<endl;
return 0;
}
C - 拿数问题 II
问题描述
给 n 个数,每一步能拿走一个数,比如拿第 i 个数, Ai = x,得到相应的分数 x,但拿掉这个 Ai 后,x+1 和 x-1 (如果有 Aj = x+1 或 Aj = x-1 存在) 就会变得不可拿(但是有 Aj = x 的话可以继续拿这个 x)。求最大分数。
Input
第一行包含一个整数 n (1 ≤ n ≤ 100000),表示数字里的元素的个数
第二行包含n个整数a1, a2, …, an (1 ≤ ai ≤ 100000)
Output
输出一个整数:n你能得到最大分值。
思路
将数字进行预处理,a[i]表示取数值为i的数字可以得到的分数。
使用f[i]存储取到数字i可以得到的最大分数。
f[i]=max(f[i-1],f[i-2]+a[i])
代码
#include<iostream>
#include<cstdio>
using namespace std;
long long a[100010];
long long f[100010];
int main()
{
int n,x,sum,max;
scanf("%d",&n);
for (int i=0;i<100001;i++)
{
a[i]=0;
f[i]=0;
}
max=0;
for (int i=0;i<n;i++)
{
scanf("%d",&x);
a[x]=a[x]+x;
if (x>max)
max=x;
}
f[0]=0;
f[1]=a[1];
for (int i=2;i<=max;i++)
if (f[i-1]>f[i-2]+a[i])
f[i]=f[i-1];
else
f[i]=f[i-2]+a[i];
printf("%lld\n",f[max]);
return 0;
}