# 15 条题解

• @ 2022-03-01 21:54:45

//100分
#include<cstdio>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,k1,k2,mod,ans=inf;
int vis[60][60];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int diamond[2600][2];
inline int abs(int x)
{
return x>0?x:-x;
}
bool check(int x,int y)
{
int a[4];
for(int i=0;i<4;i++)
{
int newx=x+dir[i][0];
int newy=y+dir[i][1];
if(newx<1||newx>n||newy<1||newy>m||vis[newx][newy]==1) a[i]=0;
else a[i]=1;
}
if(a[0]&&a[2]&&!a[1]&&!a[3]) return false;
if(!a[0]&&!a[2]&&a[1]&&a[3]) return false;
return true;
}
int magic(int step)
{
if(step<=mod) return 0;
return k1*abs(diamond[step][0]-diamond[step-mod][0])+k2*abs(diamond[step][1]-diamond[step-mod][1]);
}
void dfs(int x,int y,int step,int maxx)//step表示第step块宝石已被放下
{
if(!check(x,y)) return;
if(magic(step)>=ans) return;
if(step==n*m)
{
ans=min(ans,maxx);
return;
}
for(int i=0;i<4;i++)
{
int newx=x+dir[i][0];
int newy=y+dir[i][1];
if(newx<1||newx>n||newy<1||newy>m||vis[newx][newy]==1) continue;
vis[newx][newy]=1;
diamond[step+1][0]=newx;
diamond[step+1][1]=newy;
dfs(newx,newy,step+1,max(magic(step+1),maxx));
vis[newx][newy]=0;
}
}
int main()
{
cin>>n>>m>>k1>>k2;
mod=n*m/2;
vis[1][m]=1;
diamond[1][0]=1;
diamond[1][1]=m;
dfs(1,m,1,0);
cout<<ans;
return 0;
}

• @ 2014-07-28 16:26:15

90分，卡时没办法

• @ 2014-07-28 16:25:55

var max,sum，tot:longint;
g,j,n,m,k1,k2,i:integer;
a:array [0..51,0..51] of boolean;
b:array [1..4,1..2] of integer;
p,q:array [1..50] of integer;
f:array [0..50] of longint;

procedure data1;
begin
assign(input,'matrix.in');
assign(output,'matrix.out');
reset(input);
rewrite(output);
end;

procedure data2;
begin
close(input);
close(output);
end;

procedure data(x,y:integer);
var d,z:integer;
begin
if (sum>f[i]) and (a[x,y]) and (not((not a[x+1,y]) and (not a[x-1,y]) and (a[x,y+1]) and (a[x,y-1])) or ((not a[x,y-1]) and (not a[x,y+1]) and (a[x+1,y]) and (a[x-1,y]))) then begin
inc(tot);
if tot>=1000000 then begin writeln(sum);halt;end;
inc(i);
a[x,y]:=false;
p[i]:=x;
q[i]:=y;
if i>g then f[i]:=k1*abs(p[i-g]-x)+k2*abs(q[i-g]-y);
if i=2*g then begin
max:=0;
for z:=g+1 to 2*g do if f[z]>max then max:=f[z];
sum:=max;
dec(i);
a[x,y]:=true;
exit;
end;
for d:=1 to 4 do begin data(x+b[d,1],y+b[d,2]);end;
a[x,y]:=true;
dec(i);
end;
end;

procedure datain;
begin

fillchar(a,sizeof(a),false);
b[1,1]:=1;
b[2,1]:=-1;
b[3,2]:=-1;
b[4,2]:=1;
for i:=1 to n do
for j:=1 to m do
a[i,j]:=true;
i:=0;
sum:=maxlongint;
g:=n*m div 2;
data(1,1);
writeln(sum);

end;

begin
//data1;
datain;
//data2;
end.

• @ 2010-07-17 20:26:37

一个可行性剪枝

一个最优性剪枝

1次AC~~~

• @ 2009-11-10 16:26:00

AC了

加了一些剪枝

用马甲交了一下过了

结果用本号就 TLE 了

无语 总算过了

• @ 2009-08-21 23:07:19

译通过...

├ 测试数据 01：答案正确... 0ms

├ 测试数据 02：答案正确... 0ms

├ 测试数据 03：答案正确... 0ms

├ 测试数据 04：答案正确... 0ms

├ 测试数据 05：答案正确... 0ms

├ 测试数据 06：答案正确... 0ms

├ 测试数据 07：答案正确... 0ms

├ 测试数据 08：答案正确... 103ms

├ 测试数据 09：答案正确... 0ms

├ 测试数据 10：答案正确... 103ms

---|---|---|---|---|---|---|---|-

Accepted 有效得分：100 有效耗时：206ms

DFS+最优值剪枝+可行性剪枝=AC

• @ 2009-08-05 13:14:38

加一个连通性剪枝cena已经是1s左右AC了，VJ TLE

再加一个连通性剪枝cena已经是0.7sAC了，VJ还是TLE

真是晕倒

最后 Puppy 带领我AC了。。

• @ 2009-07-22 16:03:25

编译通过...

├ 测试数据 01：答案很正确... -1ms

├ 测试数据 02：答案超正确... -1ms

├ 测试数据 03：答案十分正确... -1ms

├ 测试数据 04：答案非常正确... -1ms

├ 测试数据 05：答案及其正确... -1ms

├ 测试数据 06：答案orz正确... -1ms

├ 测试数据 07：答案太正确了... -1ms

├ 测试数据 08：答案正确得神了... -1ms

├ 测试数据 09：答案正确得疯了... -1ms

├ 测试数据 10：答案正确让评测机爆了... -332ms

---|---|---|---|---|---|---|---|-

Accepted 有效得分：1000000 有效耗时：-1000ms

饿 你说这评测机奇怪不

• @ 2009-07-22 14:42:13

超了两点，忍无可忍，cheat了！

• @ 2009-07-10 15:07:40

var max,min:longint;

g,j,n,m,k1,k2,i:integer;

a:array [0..51,0..51] of boolean;

b:array [1..4,1..2] of integer;

p,q:array [1..50] of integer;

f:array [0..50] of longint;

procedure zou(x,y:integer);

var d,z:integer;

begin

if (min>f[i]) and (a[x,y]) and (not((not a[x+1,y]) and (not a[x-1,y]) and (a[x,y+1]) and (a[x,y-1])) or ((not a[x,y-1]) and (not a[x,y+1]) and (a[x+1,y]) and (a[x-1,y]))) then begin

inc(i);

a[x,y]:=false;

p[i]:=x;

q[i]:=y;

if i>g then f[i]:=k1*abs(p-x)+k2*abs(q-y);

if i=2*g then begin

max:=0;

for z:=g+1 to 2*g do if f[z]>max then max:=f[z];

min:=max;

dec(i);

a[x,y]:=true;

exit;

end;

for d:=1 to 4 do begin zou(x+b[d,1],y+b[d,2]);end;

a[x,y]:=true;

dec(i);

end;

end;

begin

assign(input,'mmatrix.in');reset(input);

assign(output,'mmatrix.out');rewrite(output);

fillchar(a,sizeof(a),false);

b[1,1]:=1;

b[2,1]:=-1;

b[3,2]:=-1;

b[4,2]:=1;

for i:=1 to n do

for j:=1 to m do

a:=true;

i:=0;

min:=maxlongint;

g:=n*m div 2;

zou(1,1);

writeln(min);

close(input);

close(output);

end.

• @ 2009-03-14 11:59:40

囧了,最近做题一直不顺,1184Cheat1个点,1262Cheat2个点,此题困扰一星期,只好把最后一点Cheat了

• @ 2007-11-07 11:22:45

实在不行的话卡时吧……这题如果优先水平方向再竖直方向搜的话最优解出现的挺早的

• @ 2007-07-17 22:05:24

貌似度数剪枝并没有必要啊。

编译通过...

├ 测试数据 01：答案正确... 0ms

├ 测试数据 02：答案正确... 0ms

├ 测试数据 03：答案正确... 0ms

├ 测试数据 04：答案正确... 0ms

├ 测试数据 05：答案正确... 0ms

├ 测试数据 06：答案正确... 0ms

├ 测试数据 07：答案正确... 0ms

├ 测试数据 08：答案正确... 9ms

├ 测试数据 09：答案正确... 0ms

├ 测试数据 10：答案正确... 25ms

---|---|---|---|---|---|---|---|-

Accepted 有效得分：100 有效耗时：34ms

多算一层的时间比算度数的时间还要快？

• @ 2006-11-17 12:58:37

首先一定要理解连通剪枝 然后是最优化

• @ 2006-11-02 12:40:07

8和10过不了。。哎

• 1

ID
1284

8

485

69

14%

4