2025年大一训练-DP1
- Problem A:
动态规划算法,从上往下一层层找到到达对应位置的最大值,最底下一行maxl的最大值即为答案
#include<bits/stdc++.h>
using namespace std;
int lst[101][101];
int maxl[101][101];
int main()
{
int n,i,j;
while(cin>>n)
{
memset(lst,0,sizeof(lst));
memset(maxl,0,sizeof(maxl));
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
cin>>lst[i][j];
if(i==1) maxl[i][j]=lst[i][j];
else
{
maxl[i][j]=lst[i][j]+max(maxl[i-1][j],maxl[i-1][j-1]);
}
}
}
int maxn=0;
for(j=1;j<=n;j++)
{
if(maxl[n][j]>maxn) maxn=maxl[n][j];
}
cout<<maxn<<endl;
}
return 0;
}
- Problem B:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 20;
int dp[maxn][maxn];
int main()
{
int n,i,j;
for(i=0;i<maxn;i++)
{
dp[0][i]=1;
dp[i][0]=1;
}
for(i=1;i<maxn;i++)
{
for(j=1;j<maxn;j++)
{
dp[i][j]=dp[i][j-1]+dp[i-1][j];
}
}
while(scanf("%d",&n)!=EOF&&n!=0)
{
cout<<dp[n][n]<<endl;
}
return 0;
}
- Problem C:
肯定不能每输入一次就递归,一定有测试点过不去,所以预处理202020的结果数组,然后输入查表就行了
#include<bits/stdc++.h>
using namespace std;
int f[25][25][25];
void w(int a, int b, int c)
{
if (a==0 || b==0 || c==0) f[a][b][c] = 1;
else if(a<b && b<c)
{
f[a][b][c]=f[a][b][c-1]+f[a][b-1][c-1]-f[a][b-1][c];
}
else
{
f[a][b][c]=f[a-1][b][c]+f[a-1][b-1][c]+f[a-1][b][c-1]-f[a-1][b-1][c-1];
}
}
int main()
{
int a,b,c;
int i,j,k;
for (i=0;i<21;i++)
{
for (j=0;j<21;j++)
{
for (k=0;k<21;k++)
{
w(i,j,k);
}
}
}
while (cin>>a>>b>>c)
{
if (a==-1 && b==-1 && c==-1)
{
break;
}
if (a<=0 || b<=0 || c<=0)
{
cout<<"w("<<a<<", "<<b<<", "<<c<<") = "<<1<<endl;
}
else if (a>20 || b>20 || c>20)
{
cout<<"w("<<a<<", "<<b<<", "<<c<<") = "<<f[20][20][20]<<endl;
}
else
{
cout<<"w("<<a<<", "<<b<<", "<<c<<") = "<<f[a][b][c]<<endl;
}
}
return 0;
}
- Problem D:
和前一题类似,需要预处理数组,但判断条件“and not already in the sequence”就需要用hash表去重了
#include<bits/stdc++.h>
using namespace std;
int a[500005]={0};
bool hash[100000000]={false};
int main()
{
int i,n;
for(i=1;i<=500000;i++)
{
if(a[i-1]-i>0 && !hash[a[i-1]-i]) a[i]=a[i-1]-i;
else a[i]=a[i-1]+i;
hash[a[i]]=true;
}
while(cin>>n && n!=-1) cout<<a[n]<<endl;
return 0;
}
但是题目内存受限,hash占用内存过大,可以用std::set(std::unordered_set更好),但是hash在一些版本里关键字冲突了,不建议用这个作为变量名(不然就会像我一样Compile Error四次才发现)
#include<bits/stdc++.h>
using namespace std;
int a[500001] = {0};
set<int> hashlst;
int main()
{
int i,n;
for (i=1;i<=500000;i++)
{
if (a[i-1]-i>0 && hashlst.find(a[i-1]-i)==hashlst.end())
a[i]=a[i-1]-i;
else
a[i]=a[i-1]+i;
hashlst.insert(a[i]);
}
while (cin>>n && n!=-1) cout<<a[n]<<endl;
return 0;
}
- Problem E:
下面是我为人人的具体代码实现
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
int a;
int x,y;
}Node;
Node node[10010];
int n,m;
int lst[110][110];
int len[110][110];
int dirx[4] = {1,0,-1,0};
int diry[4] = {0,1,0,-1};
bool cmp(const Node& n,const Node& m)
{
return n.a<m.a;
}
int main()
{
cin>>n>>m;
int p=0,i,j;
for(i=1;i<=n;++i)
{
for(j=1;j<=m;++j)
{
cin>>lst[i][j];
len[i][j]=0;
node[p].a=lst[i][j];
node[p].x=i;
node[p++].y=j;
}
}
sort(node,node+p,cmp);
for(i=0;i<p;i++)
{
int l=1;
for(j=0;j<4;j++)
{
int dx = node[i].x+dirx[j];
int dy = node[i].y+diry[j];
if(dx>0 && dy>0 && dx<=n && dy<=m && lst[dx][dy]<node[i].a)
l=max(l,len[dx][dy]+1);
}
len[node[i].x][node[i].y]=max(l,len[node[i].x][node[i].y]);
}
int Max=-1;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
Max=max(Max,len[i][j]);
}
cout<<Max<<endl;
return 0;
}