您的位置:首页 > Web前端

POJ 2609 Ferry Loading

2016-03-10 12:09 357 查看
双塔DP+输出路径。

由于内存限制,DP只能开滚动数组来记录。

我的写法比较渣,但是POJ能AC,但是ZOJ依旧MLE,更加奇怪的是Uva上无论怎么改都是WA,其他人POJ过的交到Uva也是WA。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<algorithm>
using namespace std;

int dp[2][20000+10];
struct P
{
int x,y;
int f;
}pre[505][20000+10];
int sum;
int a[505],tot;

void read()
{
while(1)
{
scanf("%d",&a[tot+1]);
if(a[tot+1]==0) break;
tot++;
}

for(int i=0;i<=tot;i++)
for(int j=0;j<=2*sum;j++)
pre[i][j].f=-1;

for(int j=0;j<=2*sum;j++) dp[1][j]=dp[0][j]=0x7FFFFFFF;
}

void init()
{
sum=sum*100;
tot=0;
}

void work()
{
int now=0;
dp[0][a[1]+sum]=0;
pre[1][a[1]+sum].f=0;
dp[0][0-a[1]+sum]=0;
pre[1][0-a[1]+sum].f=1;

for(int i=2;i<=tot;i++)
{
now=now^1;
for(int j=0;j<=2*sum;j++) dp[now][j]=0x7FFFFFFF;
for(int j=0;j<=2*sum;j++)
{
if(dp[now^1][j]==0x7FFFFFFF) continue;

int tmp=j-sum;

if(tmp>=0)
{
if(dp[now^1][j]+tmp+a[i]<=sum&&dp[now^1][j]<dp[now][tmp+a[i]+sum])
{
dp[now][tmp+a[i]+sum]=dp[now^1][j];
pre[i][tmp+a[i]+sum].x=i-1;
pre[i][tmp+a[i]+sum].y=j;
pre[i][tmp+a[i]+sum].f=0;
}

if(max(tmp,a[i])+dp[now^1][j]<=sum&&dp[now^1][j]+min(tmp,a[i])<dp[now][tmp-a[i]+sum])
{
dp[now][tmp-a[i]+sum]=dp[now^1][j]+min(tmp,a[i]);
pre[i][tmp-a[i]+sum].x=i-1;
pre[i][tmp-a[i]+sum].y=j;
pre[i][tmp-a[i]+sum].f=1;
}
}

else
{
tmp=-tmp;
if(dp[now^1][j]+tmp+a[i]<=sum&&dp[now^1][j]<dp[now][0-(tmp+a[i])+sum])
{
dp[now][0-(tmp+a[i])+sum]=dp[now^1][j];
pre[i][0-(tmp+a[i])+sum].x=i-1;
pre[i][0-(tmp+a[i])+sum].y=j;
pre[i][0-(tmp+a[i])+sum].f=1;
}

if(max(tmp,a[i])+dp[now^1][j]<=sum&&dp[now^1][j]+min(tmp,a[i])<dp[now][a[i]-tmp+sum])
{
dp[now][a[i]-tmp+sum]=dp[now^1][j]+min(tmp,a[i]);
pre[i][a[i]-tmp+sum].x=i-1;
pre[i][a[i]-tmp+sum].y=j;
pre[i][a[i]-tmp+sum].f=0;
}

}
}
}
}

void output()
{
bool flag=0;
int now_i,now_j;
for(int i=tot;i>=1;i--)
{
for(int j=2*sum;j>=0;j--)
{
if(pre[i][j].f!=-1)
{
now_i=i;
now_j=j;
flag=1;
break;
}
}
if(flag) break;
}

if(flag==0) {printf("0\n");return;}
printf("%d\n",now_i);

stack<int>S;

while(1)
{
if(pre[now_i][now_j].f==-1) break;
S.push(pre[now_i][now_j].f);

int newx,newy;
newx=pre[now_i][now_j].x;
newy=pre[now_i][now_j].y;
now_i=newx;
now_j=newy;
}

int k=1;
int left=0;
int right=0;

while(!S.empty())
{
if(S.top()==0)
{
printf("port\n");
left=left+a[k];k++;
}
else
{
printf("starboard\n");
right=right+a[k];k++;
}
S.pop();
}
}

int main()
{
scanf("%d",&sum);
init();
read();
work();
output();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: