标签:bzoj bzoj3628 记忆化搜索 dp 动态规划
题意:。。。给定一个矩阵,每个点有一堆金币,自己在(0,1),然后各种跳,求最大收益(具体自己看)
传说中的省选第二题,当时写的爆搜20分,现在想想把深搜改成广搜再加个记忆化不就切了么。。。不过这题要开滚动数组 直接交MLE
正解应该是DP 我实在懒得DP就记忆化搜索了 反复memset那里常数有点大 懒得处理了
我自然溢出的队列居然写挂了。。。直接把h-1写在中括号里会强制类型转换成int导致调用q[-1] 所以只能这样了
交的人好少。。这题也没啥意思 水水就切了
注意这题无论是数组还是读入输出都非常容易弄反 小心点就行
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct abcd{ int x,y; int power,times; }q[65540],empty; unsigned short r,h; int n,m,cost1,cost2,ans=0xefefefef,ansh,ansc; int height,comble; int map[30][100100]; int f[2][31][20][6]; int g[2][100100]; void Cheat() { int i; for(i=1;i<=n;i++) { if(~map[1][i]) g[0][i]=max( g[0][i-1] , g[1][i-1] )+map[1][i]; else g[0][i]=0xefefefef; if(~map[2][i]) g[1][i]= g[0][i-1] +map[2][i]; else g[1][i]=0xefefefef; } ans=max(g[0][n],g[1][n]); if(ans<0) puts("mission failed"); else printf("%d %d %d\n",ans,1,1); exit(0); } void Move(abcd now,int x,int y,int power,int times) { if( ~map[y][x] ) { if(f[x&1][y][power][times]<0) { q[++r].x=x; q[r].y=y; q[r].power=power; q[r].times=times; } f[x&1][y][power][times]=max(f[x&1][y][power][times],f[now.x&1][now.y][now.power][now.times]+map[y][x]); } } void Memory_Search() { int nowans=0xefefefef; r=h=0; q[0]=empty; q[++r]=q[0]; q[r].y=1; memset(f,0xef,sizeof f); f[0][1][0][0]=0; while(r!=h) { abcd now=q[++h];--h; if(now.x!=q[h].x) memset(f[~now.x&1],0xef,sizeof f[0]); ++h; if(now.x==n) { nowans=max(nowans,f[now.x&1][now.y][now.power][now.times]); continue; } if(now.power) { Move(now,now.x+1,now.y+1,now.power-1,now.times); continue; } if(now.y==1) { Move(now,now.x+1,1,0,0); Move(now,now.x+1,2,height-1,1); } else { if(now.times!=comble) Move(now,now.x+1,now.y+1,height-1,now.times+1); Move(now,now.x+1,now.y-1,0,now.y==2?0:now.times); } } nowans-=(height-1)*cost1+(comble-1)*cost2; if(nowans>ans) ans=nowans,ansh=height,ansc=comble; } int main() { //freopen("parkour.in","r",stdin); //freopen("parkour.out","w",stdout); int i,j; cin>>n>>m>>cost1>>cost2; for(i=1;i<=m;i++) for(j=1;j<=n;j++) scanf("%d",&map[i][j]); if(m==2) Cheat(); for(comble=1;comble<=5;comble++) for(height=1;comble*height<m;height++) Memory_Search(); if(ans<0) puts("mission failed"); else printf("%d %d %d\n",ans,ansc,ansh); }
标签:bzoj bzoj3628 记忆化搜索 dp 动态规划
原文地址:http://blog.csdn.net/popoqqq/article/details/39157703