zjut1633——好简单的动态规划

本文介绍了一个关于接取樱花花瓣的问题,并提供了一种使用动态规划算法求解的方法。该问题要求计算在一个给定的时间和坐标下,角色Zero能够接住的最大数量的樱花花瓣。文章中详细展示了如何通过动态规划来解决这个问题,包括状态转移方程的设计及其实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem A: Zero的樱花

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 75   Solved: 26
[ Submit][ Status][ Web Board]

Description

十日樱花作意开,绕花岂惜日千回?昨宵风雨偏相厄,谁向人天诉此哀?
忍见胡沙埋艳骨,空将清泪滴深怀。多情漫作他年忆,一寸春心早已灰。(黄季刚)
Zero不忍樱花就此落地,希望在樱花落地前接住落下的花瓣。Zero通过其强大的人脑计算能力,能够算出每一片樱花将在何时何地处于他能接住的高度,Zero必须刚好在那个时刻那个地点才能接住花瓣,如果迟到了会导致樱花飘落地面。
Zero十分灵活,每秒能够向东南西北任意一个方向移动1米,或者停留在原地,以便能够接到其他地方的樱花。Zero的初始位置可任选。
请你帮Zero算一下,他最多能接到多少片樱花花瓣?

Input

多组数据输入,第一行输入一个整数n(n<=20),表示有多少组数据。
    对于每组数据,先输入一个m(m<=100),表示花瓣数量。
    接下来m行,每行代表一个花瓣,包含三个数据t(0<=t<=100)、x、y(0<x,y<=20),分别表示花瓣飘落到可接住高度的时间、横坐标、纵坐标。

Output

对于每组数据,输出一行,表示Zero最多能接到的花瓣数目。

Sample Input

1
5
0 10 10
1 11 10
1 11 11
2 10 9
3 10 11

Sample Output

3




很明显,t时刻xy位置时,后面可得到的花瓣数量是可以被已知的,动态规划即可。
#include<iostream>
#include<algorithm>
#include <stdio.h>
#include<stdlib.h>
#include<string>
using namespace std;
#define M 100010

int ans[105][22][22],flower[105][22][22];

int dp(int t,int x,int y)
{
	int now_ans,maxx,xx,yy;
	if(ans[t][x][y]!=-1)
		return ans[t][x][y];
	maxx=-1;
	xx=x-1;
	yy=y;
	if(xx>0)
	{
		now_ans=flower[t][x][y]+dp(t+1,xx,yy);
		if(now_ans>maxx)
			maxx=now_ans;
	}
	
	xx=x+1;
	yy=y;
	if(xx<=20)
	{
		now_ans=flower[t][x][y]+dp(t+1,xx,yy);
		if(now_ans>maxx)
			maxx=now_ans;
	}

	xx=x;
	yy=y+1;
	if(yy<=20)
	{
		now_ans=flower[t][x][y]+dp(t+1,xx,yy);
		if(now_ans>maxx)
			maxx=now_ans;
	}

	xx=x;
	yy=y-1;
	if(yy>0)
	{
		now_ans=flower[t][x][y]+dp(t+1,xx,yy);
		if(now_ans>maxx)
			maxx=now_ans;
	}

	xx=x;
	yy=y;
	now_ans=flower[t][x][y]+dp(t+1,xx,yy);
	if(now_ans>maxx)
		maxx=now_ans;
	
	ans[t][x][y]=maxx;
	return ans[t][x][y];
}


int main()
{
	int t,x,y,i,j,n,m,maxx;
	scanf("%d",&n);
	while(n--)
	{
		for(t=0;t<=100;t++)
			for(x=1;x<=20;x++)
				for(y=1;y<=20;y++)
				{
					flower[t][x][y]=0;
					ans[t][x][y]=-1;
				}

		scanf("%d",&m);
		while(m--)
		{
			scanf("%d%d%d",&t,&x,&y);
			flower[t][x][y]=1;
		}

		maxx=-1;
		for(i=1;i<=20;i++)
			for(j=1;j<=20;j++)
			{
				if(dp(0,i,j)>maxx)
					maxx=dp(0,i,j);
			}
		printf("%d\n",maxx);
	}
}	








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值