hdu1176 免费馅饼
传送门
有一个长度为11(标号从0到10)的数轴,n个馅饼分别在时间t掉落在点x上。有一个人在时刻0位于x=5处,每一秒可以移动到左右两端的位置并且接住那一秒掉落在相应位置的馅饼,他也可以选择不移动接住掉落在当前位置的馅饼。求出他能接到的馅饼数量的最大值。
0<n,t<100000,0<=x<=10。
类似于数字三角形问题。
矩阵dp[t][x]表示第t秒掉落在位置x上的馅饼个数,首先把初始数据填入矩阵,之后以时间为层从大到小按照数字三角形的思维逐层处理,最大值存储在dp[0][5]中。
以样例为例子,第1秒在4,5,6位置分别有1个馅饼掉落,第2秒在7位置有2个馅饼掉落,第3秒在8位置有1个馅饼掉落,填入初始数据的矩阵:
从上到下逐层处理,将当前位置的值加上上一层临近的三个位置中的最大值,处理之后的矩阵:
\(
\left[
\begin{matrix}
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 3 & 1 & 1 & 0\ 0 & 0 & 0 & 0 & 1 & 1 & 4 & 3 & 3 & 1 & 1\ 0 & 0 & 0 & 1 & 1 & 4 & 4 & 4 & 3 & 3 & 1
\end{matrix}
\right]
\)
其中dp[0][5]==4,所以最大值为4。
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
using namespace std;
int n,dp[100010][15];
int main(void){
while(scanf("%d",&n)!=EOF && n){
memset(dp,0,sizeof(dp));
int maxt=0;
for(int i=1;i<=n;i++){
int x,t;
scanf("%d %d",&x,&t);
dp[t][x]++;
maxt=max(maxt,t);
}
for(int i=maxt-1;i>=0;i--){
for(int j=0;j<11;j++){
int t1=0,t2=dp[i+1][j],t3=0;
if(j-1>=0) t1=dp[i+1][j-1];
if(j+1<11) t3=dp[i+1][j+1];
dp[i][j]+=max(max(t1,t2),t3);
}
}
printf("%d\n",dp[0][5]);
}
return 0;
}
原文:https://www.cnblogs.com/fxq1304/p/13051191.html