2563:对于每个i , j只能由i-1 j和i-1 j-1前往
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n;
int a[N][N], f[N][N];
int main(){
cin >> n;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= i; j ++ )
cin >> a[i][j];
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= i; j ++ )
f[i][j] = a[i][j] + max(f[i - 1][j], f[i- 1][j - 1]);
int maxn = 0;
for (int i = 1; i <= n; i ++ ) maxn = max(maxn, f[n][i]);
cout << maxn << endl;
return 0;
}
2564,把马占的九个点(如果存在)标记,然后dp
#include<bits/stdc++.h>
using namespace std;
int dx[9]={0,-2,-1,1,2,2,1,-1,-2};
int dy[9]={0,1,2,2,1,-1,-2,-2,-1};
int main()
{
int m , n , x, y;
long long int f[30][30]={0};
int g[30][30]={0};
cin >> n >> m >> x >> y;
g[x][y]=1;
for(int i=1;i<=8;i++)
if(x+dx[i]>=0&&x+dx[i]<=n&&y+dy[i]>=0&&y+dy[i]<=m)
g[x+dx[i]][y+dy[i]]=1;
for(int i=1;i<=n;i++)
{
if(g[i][0]!=1)
f[i][0]=1;
else
for(;i<=n;i++)
{
f[i][0]=0;
}
}
for(int j=1;j<=m;j++)
{
if(g[0][j]!=1)
f[0][j]=1;
else
for(;j<=m;j++)
f[0][j]=0;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(g[i][j]==1)
f[i][j]=0;
else
f[i][j]=f[i-1][j]+f[i][j-1];
}
}
cout << f[n][m];
return 0;
}
2565:只能由左手和右手穿过来,对于1和n特判即可
#include<bits/stdc++.h>
using namespace std;
int f[40][40],m,n;
int main()
{
cin>>n>>m;
f[0][1]=1;
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
if(j==1)
f[i][j]=f[i-1][n]+f[i-1][2];
else if(j==n)
f[i][j]=f[i-1][1]+f[i-1][n-1];
else
f[i][j]=f[i-1][j-1]+f[i-1][j+1];
cout<<f[m][1]<<endl;
return 0;
}
2566,2567:LIS,第一个可以用dp,第二个会超时,采用贪心+二分
dp:
#include<bits/stdc++.h>
using namespace std;
int f[10010];
int a[10010];
int main(){
int n;
cin>>n;
int ans=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
f[i]=1;
for(int j=1;j<i;j++)
{
if(a[j]<a[i])
{
f[i]=max(f[i],f[j]+1);
}
}
}
for(int i=1;i<=n;i++)
{
ans=max(ans,f[i]);
}
cout<<ans;
return 0;
}
贪心+二分
#include<bits/stdc++.h>
using namespace std;
int a[100010];
int f[100010];
int n,R,l,r,mid,ans;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
f[0]=0;
R=0;
for(int i=1;i<=n;i++)
{
if(a[i]>f[R])
{
f[R+1]=a[i];
R++;
}
else
{
l=0;
r=R;
while(l<=r)
{
mid=(l+r)/2;
if(f[mid]<a[i])
{
l=mid+1;
}
else
{
ans=mid;
r=mid-1;
}
}
f[ans]=a[i];
}
}
int t=0;
for(int i=1;i<=n;i++)
{
if(f[i])
{
t++;
}
}
cout<<t;
return 0;
}