题意:。。。给定一个矩阵,每个点有一堆金币,自己在(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);
}