Free pie (HDU-1176)

Posted by audiodef on Sat, 19 Feb 2022 02:41:25 +0100

Title Link:
http://acm.hdu.edu.cn/showproblem.php?pid=1176
Main idea of the title:
At first, the gameboy is on coordinate 5. He can only move in 0-10 coordinates, and the gameboy at position I can only connect the pie at one position of (i-1),(i),(i+1) in the next second (there may be more than one pie falling at this time). Find out how many pies she can connect in the end

Topic analysis:
Big guys classify this problem as the problem of counting towers. If students who have done counting towers should be possible and may do... (the most basic problem of counting towers is not difficult, you can go and have a look),
But even if I read the number tower, I can't understand how to write the problem at once. The advanced problem of the algorithm is here. You may not be able to see what algorithm he wants to use at once. Even if someone tells you what algorithm to use, you may not understand it at once... (a little nonsense). If you understand the number tower, but don't know the method of the problem very well, you can draw the following figure, Take your time. You should understand.

What I didn't say here is very detailed. I just took out the problems I encountered and shared them with you. What I said may not be very good. Forgive me!!

After reading many codes written by others, they are pushed backwards. Combined with the number tower model, this code can be written (AC). The code is as follows:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>

using namespace std;
//You should know about the number tower first, 
const int N=100005;
int dp[N][12];
int main()
{
	int n;
	int x,T; 
	while(scanf("%d",&n)==1&&n!=0)
	{
		memset(dp,0,sizeof(dp));
		int m=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&x,&T);
			dp[T][x]++;
			if(T>m)
			m=T;
		}
		for(int i=m-1;i>=0;i--)//time 
		for(int j=0;j<11;j++)//position
		{
		if(j==0)
		dp[i][j]+=max(dp[i+1][j],dp[i+1][j+1]);
		else if(j==10)
		dp[i][j]+=max(dp[i+1][j-1],dp[i+1][j]);
		else
		dp[i][j]+=max(dp[i+1][j-1],max(dp[i+1][j],dp[i+1][j+1]));
		}
		
		 printf("%d\n",dp[0][5]);
	}
	return 0;
 } 
		

However, at that time, I thought this question could be pushed forward, and then I thought briefly and wrote the following error code. As expected, I thought it was simple. I think someone might be like me, so I posted it (error code), and the code is as follows:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std; 
const int N=100005;
int dp[N][12];
int main()
{
	int n;
	int x,T; 
	while(scanf("%d",&n)==1&&n!=0)
	{
		memset(dp,0,sizeof(dp));
		int m=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&x,&T);
			dp[T][x]++;
			if(T>m)
			m=T;
		}
		for(int i=1;i<=m;i++)//time 
		for(int j=0;j<11;j++)//position
		dp[i][j]+=max(dp[i-1][j-1],max(dp[i-1][j],dp[i-1][j+1]));//There will be cross-border situations. Sometimes it will not work. I didn't write it here. Remember to write it. How to write it? The code above can be used for reference
		 printf("%d\n",dp[0][5]);
	}
	return 0;
 }

See if this code is not a big problem and should be able to pass
nonono, this idea is not a correct idea. Remember that the topic is to start with coordinate 5 and finally calculate the maximum value of pie. This code is no longer the original idea. Its current meaning is to start from each point and finally reach the maximum value of pie at coordinate 5.

In fact, I thought for a long time here and finally asked the boss of our class. In fact, whether it is reverse push or forward push, we all ask dp[0][5] (0 second time, position 5). The code written by the boss (AC) (forward push) is attached below:

# include <stdio.h>
# include <algorithm>
# include <cstring>
# define max3(a,b,c)  max(max((a),(b)),(c))
using namespace std;

const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
int n;
int dp[12][maxn];

int main()  {
    while(scanf("%d",&n) != EOF)    {
        if(!n)  break;
        int MAX_TIME = 0;
        memset(dp,0,sizeof dp);
        for(int i = 0; i < n; i++)  {
            int a, b;//a represents time and b represents position.
            scanf("%d%d",&a,&b);
            dp[a][b]++;
            MAX_TIME = max(MAX_TIME,b);
        }

        for(int i = 0; i <= 11; i++)    {
            if(i >= 4 && i <= 6)  ;
            else dp[i][1] = -INF;
        }


        for(int j = 2; j <= MAX_TIME; j++)  {

            for(int i = 0; i <= 10; i++)    {
                if(i == 0) dp[i][j] += max(dp[i][j-1],dp[i+1][j-1]);
                else if(i == 10)    dp[i][j] += max(dp[i][j-1],dp[i-1][j-1]);
                else
                dp[i][j] += max3(dp[i-1][j-1],dp[i][j-1],dp[i+1][j-1]);
            }
        }
        int MAX = 0;
        for(int i = 0; i <= 10; i++)    {
            if(dp[i][MAX_TIME] > MAX)   MAX = dp[i][MAX_TIME];
        }
        printf("%d\n",MAX);
    }

    return 0;
}

Topics: C++ Algorithm