记录编号 446548 评测结果 WAAAWA
题目名称 [NOI 1998]免费馅饼 最终得分 66
用户昵称 GravatarArrow 是否通过 未通过
代码语言 C++ 运行时间 0.000 s
提交时间 2017-09-08 16:22:20 内存使用 0.00 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define MAXW 110
#define MAXT 1010

	int w,h,max_t=0,start_pos=0,ans=0;
	int g[MAXW][MAXT]={0},f[MAXW][MAXT]={0},p[MAXW][MAXT]={0};
		// f[i][j] means in the position i and at time j the max points
		// g[i][j] notes the number of pizzas which are in the position i and at time j
		// p[i][j] notes the choice which leads to state f[i][j]
	int move[5]={2,1,0,-1,-2};// four kinds of movements

void work()
{
	start_pos=(1+w)/2;
	memset(f,-1,sizeof(f));
	memset(p,-1,sizeof(p));
	f[start_pos][0]=g[start_pos][0];
	if(f[start_pos][0]!=0)
		p[start_pos][0]=2;
	for(int j=1;j<=max_t;j++)
	{
		for(int i=1;i<=w;i++)
		{
			for(int k=5;k>=0;k--) //k 代表到达该状态所使用的方案,为了保证字典序应尽量由左边转移来
			{
				if(i+move[k]<1||i+move[k]>w) continue;
				//if(f[i+move[k]][j-1]!=-1)
					if(f[i][j]<f[i+move[k]][j-1]+g[i][j])
					{
						f[i][j]=f[i+move[k]][j-1]+g[i][j];
						p[i][j]=k;
					}
			}
		}
	}
	
}

int getans()
{
	int max_i,max_j;
	for(int i=1;i<=w;i++)
	{
		for(int j=0;j<=max_t;j++)
		{
			if(ans<f[i][j])
			{
				ans=f[i][j];
				max_i=i;
				max_j=j;
			}
		}
	}
	printf("%d\n",ans);
	int cur_i=max_i,cur_j=max_j;
	int tmp[MAXT]={0};
	if(cur_j==0&&ans!=0)
	{
		printf("%d\n",move[p[cur_i][cur_j]]);
		return 0;
	}
	while(cur_j>=0)
	{
		tmp[cur_j-1]=-move[p[cur_i][cur_j]];
		cur_i+=move[p[cur_i][cur_j]];
		cur_j--;  //time move 1 second forward
	}
	for(int i=0;i<max_j;i++)
		printf("%d\n",tmp[i]);
	return 1;
}

int main()
{
	freopen("freepizza.in","r",stdin);
	freopen("freepizza.out","w",stdout);
	scanf("%d%d",&w,&h);
	int st,sp,speed,val;
	while(scanf("%d%d%d%d",&st,&sp,&speed,&val)!=EOF)
	{
		if(((h-1)/speed>=1&&(h-1)%speed==0)||st==0)
		{
			g[sp][(h-1)/speed+st]+=val;
			max_t=max(max_t,(h-1)/speed+st);
		}
	}
	work();
	getans();
return 0;
}