记忆化搜索 区间dp uva629

来源:互联网 发布:码栈完善聚划算编程 编辑:程序博客网 时间:2024/05/17 07:05

记忆化搜索 区间dp uva629

这题一看就知道是区间dp 状态定义很简单 但是在写代码的时候 有个地方一直错 错到我吐血 下面代码中有写

d(x,y,k,h)表示x行到y行 k列到h列的最少数 也就是子矩形的宽度和高度

d(x,y,k,h)=min(d(x,i,k,h)+d(i,y,k,h)+h-k)  列的枚举也是如此

#include <iostream> #include <string.h> using namespace std;const int inf = 0x3f3f3f3f;int n,m,l,d[25][25][25][25];int map[25][25];int getsum(int x,int y,int k,int h){int sum=0;for(int i=x+1;i<=y;i++)for(int j=k+1;j<=h;j++){if(map[i][j])sum++;if(sum>=2)return sum;}return sum;}int dp(int x,int y,int k,int h)//表示的半开半闭  {int &ans=d[x][y][k][h];if(ans!=-1) return ans;int num=getsum(x,y,k,h);if(num==1) return ans=0;//如果只有一个了就不用分了 if(!num) return ans=inf;//如果0个 那么就是不能这样分 放回无穷大 ans=inf; for(int i=x+1;i<y;i++)ans=min(ans,dp(x,i,k,h)+dp(i,y,k,h)+h-k);for(int j=k+1;j<h;j++)ans=min(ans,dp(x,y,k,j)+dp(x,y,j,h)+y-x);return ans;}int main(){int cas=1;while(~scanf("%d%d%d",&n,&m,&l)){memset(d,-1,sizeof(d));memset(map,0,sizeof(map));for(int i=0;i<l;i++){int x,y;scanf("%d%d",&x,&y);map[x][y]=1;}printf("Case %d: %d\n",cas++,dp(0,n,0,m));//这个地方 按照理解是从1开始 但是一直//写不出来 }return 0;}



0 0