A - 签到题
解题过程
使用递归,当达到要求数值时返回操作次数,当n>m时说明转化不了输出-1.
#include <iostream>
using namespace std;
int f=0,c=0;
void dfs(int n,int m,int count)
{ if(n>m||f==1)
return ;
if(n==m)
{ f=1;
c=count;
return;
}
dfs(n*2,m,count+1);
dfs(n*3,m,count+1);
}
int main(int argc, char** argv) {
int n,m;
cin>>n>>m;
dfs(n,m,0);
if(f==0)
cout<<-1<<endl;
else
cout<<c<<endl;
return 0;
}
B - LIS & LCS
解题过程
LIS最长上升子序列,可以使用动态规划思想求解。f[i]为以ai为末尾的最长上升子序列长度,一开始视所有序列只包含ai一个数所以f[i]初始化为1,最大的f[i]就是本题的答案。在满足序列上升的同时保证 dp[ i ] 尽可能大,当a[j]<a[i]时说明a[i]末尾的序列可以加入a[j]即f[i]=max(f[i],f[j]+1)。
LCS最长公共子序列,也是动态规划。dp[i][j] 为序列A1—Ai和B1—Bj的LCS长度,对两个序列进行遍历,如果Ai=Bj,则dp[i+1][j+1]就是dp[i][j]+1,即加入了一个新数,如果不等于则dp[i+1][j+1]就是g[ i ] [j-1]和g[i-1][j]中的最大值,即A1—Ai与B1—Bj-1和A1—Ai-1与B1—Bj的最长公共子序列的较长者。
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int a[5020];
int b[5020];
int f[5020],dp[5020][5020];
int n,m,ansa,ans;
void maxlis()
{ for(int i=1;i<=n;i++)
{ for(int j=1;j<=i;j++)
{if(a[j]<a[i])
f[i]=max(f[i],f[j]+1);
}
if(f[i]>ansa)
ansa=f[i];
}
}
void maxlcs()
{ for(int i=1;i<=n;i++)
{ for(int j=1;j<=m;j++)
{if(b[j]==a[i])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}
ans=dp[n][m];
}
int main(int argc, char** argv) {
memset(f, 0, sizeof(f));
memset(dp, 0, sizeof(dp));
ansa=0;ans=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
f[i]=1;
}
for(int i=1;i<=m;i++)
cin>>b[i];
maxlis();
maxlcs();
cout<<ansa<<" "<<ans;
}
C - 拿数问题 II
Input
2
1 2
Output
2
Input
3
1 2 3
Output
4
Input
9
1 2 1 3 2 2 2 2 3
Output
10
解题过程
需要求出最大分值,用一个数组b统计数组a中每个数出现的个数,dp[i]指拿小于等于i分的数中能拿到的最大分数。拿了i后,i+1与i-1不能再被拿所以dp[i]=max(dp[i-2]+b[i]*i,dp[i-1]),答案为dp数组中最大的数。
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
long long a[100020];
long long b[100020],dp[100020];
long long n,ans=0;
long long minn=100020,maxn=-1;
void dpp()
{
for(long long i=minn;i<=a[n];i++)
{ if(i-2>0)
dp[i]=max(dp[i-2]+b[i]*i,dp[i-1]);
else
dp[i]=max(dp[0]+b[i]*i,dp[i-1]);
ans=max(ans,dp[i]);
}
}
int main(int argc, char** argv) {
memset(b, 0, sizeof(b));
memset(dp, 0, sizeof(b));
ans=0;
cin>>n;
for(long long i=1;i<=n;i++)
{
cin>>a[i];
b[a[i]]++;
minn=min(a[i],minn);
}
sort(a+1,a+1+n);
dpp();
cout<<ans;
}