【dp每日一题】HDU 1176 免费馅饼

大意:

有n个馅饼在不同的时间会落到0到10的区间内,初始位置为5,每秒只能移动一米,问最多能接到多少馅饼

思路:

既可以正着写也可以反着写,正着写的话需要判断能否达到这个点,反着写就无所谓了

正着写:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
typedef long long LL;
int n, mp[N][20], dp[N][20];
int main() {
    while (scanf("%d", &n) && n != 0) {
        int x, t;
        int lastt = 0;
        memset(mp, 0, sizeof mp);
        memset(dp, 0xc0, sizeof dp);
        for (int i = 0; i < n; i++) {
            scanf("%d%d", &x, &t);
            mp[t][x]++;
            lastt = max(lastt, t);
        }
        dp[0][5] = 0;
        for (int i = 1; i <= lastt; i++) {
            for (int j = 0; j <= 10; j++) {
                if (j != 0)
                    dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]);
                if (j != 10)
                    dp[i][j] = max(dp[i][j], max(dp[i-1][j],dp[i - 1][j + 1]));
                if(dp[i][j]!=int(0xc0c0c0c0)){
                    //cout << dp[i][j] << endl;
                    dp[i][j] += mp[i][j];
                }
                //cout << i << ' ' << j << ' ' << dp[i][j] << endl;
            }

        }
        int res = 0;
        for (int i = 0; i <= 10;i++){
            res = max(res, dp[lastt][i]);
        }
        printf("%d\n", res);
    }
    return 0;
}

反着写:

#include<bits/stdc++.h>

using namespace std;

int i,j,n,dp[100005][20],maxn,x,t;

int main()
{
	while(scanf("%d",&n),n!=0)
	{
		memset(dp,0,sizeof(dp));
		maxn=0;
		for(i=1;i<=n;i++)
		{
			scanf("%d%d",&x,&t);
			dp[t][x]++;
			if(t>maxn)
			maxn=t;
		}
		for(i=maxn-1;i>=0;i--)
		{
			dp[i][0]+=max(dp[i+1][0],dp[i+1][1]);
			dp[i][10]+=max(dp[i+1][10],dp[i+1][9]);
			for(j=1;j<=9;j++)
			{
				dp[i][j]+=max(dp[i+1][j],max(dp[i+1][j-1],dp[i+1][j+1]));
			}
		}
		printf("%d\n",dp[0][5]);
	}
}

上一篇:一些DP题(顺便找的)


下一篇:9.19 考试总结