【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]);
}
}