坐标DP
坐标DP
题如其名,该类型的DP以坐标的形式出现,也是以坐标为元素进行深搜。
该类型的DP问题还是比较简单的。
一.传纸条

这道题找的是从a[0][0]到a[m][n]的两条不相交的路径,并让这两条路径上的点的值和最大。f[i][j][k][l]表示第一条路走到a[i][j],第二条路走到a[k][l]时好感度和的最大值。
DP时分四种情况,还要注意判断两条路径是否相交。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int f[N][N][N],w[N][N];
int n,m,i,j;
int main(){
cin>>m>>n;
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
scanf("%d",&w[i][j]);
}
}
for(int k=1;k<=(n+m-1);k++){
for(i=1;i<=m;i++){
for(j=1;j<=m;j++){
if(k-i+1>0&&k-j+1>0&&k-i+1<=n&&k-j+1<=n){
int t=f[k][i][j];
t=max({t,f[k-1][i-1][j],f[k-1][i][j-1],f[k-1][i-1][j-1],f[k-1][i][j]});
if(i!=j)t+=w[i][k-i+1]+w[j][k-j+1];
else t+=w[i][k-i+1];
f[k][i][j]=t;
}
}
}
}
cout<<f[n+m-1][m][m];
return 0;
}
2.盖房子

该题有两种方法,一种是常规的坐标DP,另一种是不那么常规的二分答案(也是我自己想出来的“歪门邪道”)
法一:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int a,b,c[2002][2002],f[2002][2002],ans;
int main(){
scanf("%d%d",&a,&b);
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++){
scanf("%d",&c[i][j]);
}
}
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++){
if(c[i][j]==1){
f[i][j]=min(f[i-1][j-1],min(f[i-1][j],f[i][j-1]))+1;
ans=max(ans,f[i][j]);
}
}
}
printf("%d",ans);
return 0;
}
常规DP,每一个为1的方块都自成一个正方形,若一个方块的左上,左,上的三个方块都是1,则该方块可以变成2,(代表该方块为右下角的正方形的边长(此处因人而异,看怎么定义位置了,核心就是用一个角上的方块代表整个正方形)),推广一下,会发现,一个方块可以变成它左上、左、上三个位置方块代表数的最小值+1。
可推出状态转移方程: f[i][j]=min(f[i-1][j-1],min(f[i-1][j],f[i][j-1]))+1
还要注意遍历顺序,要是选左下角那个方块为代表,就向右上遍历,总之就是向相反方向遍历,这样一遍就可以得出答案。
法二:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1001;
int g[N][N];
int i,j,n,len,o,m,ans,l,r;
bool check(int x,int y,int l){
for(int i=x;i<=x+l-1;i++){
for(int j=y;j<=y+l-1;j++){
if(!g[i][j])return false;
}
}
o=1;
return true;
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%d",&g[i][j]);
}
}
r=min(m,n);
while(l<=r){
int mid=(l+r)>>1;
for(i=1;i<=n-mid+1;i++){
for(j=1;j<=m-mid+1;j++){
if(check(i,j,mid)){
ans=mid;
break;
}
}
if(o)break;
}
if(o){
l=mid+1;
o=0;
}else r=mid-1;
}
printf("%d",ans);
return 0;
}
遍历点时正方形的彼岸可能会越出矩形,所以i从1循环到n-mid+1,j从1循环到m-mid+1,这样既可以避免不必要的错误,又节省了空间和时间。
该方法的时间复杂度跟spfa一样,非常玄学,看似至少有O(n4)的时间复杂度,但是实测的时候实际复杂度可能不到O(n4)。
三.三角蛋糕
该题和盖房子基本可以说是完全一致,但是需要注意三角形的朝向问题(用最左边小三角的横坐标的奇偶即可判断),也是两种方法。
浙公网安备 33010602011771号