無料のパイ
空にパイが落ちることはないと言われていますが、ある日、ゲームボーイが帰り道を歩いていたところ、突然たくさんのパイが空から落ちました。このゲームボーイのキャラクターは本当に良いです、このパイは他のどこにも落ちませんでした、それは彼の側から10メートル以内に落ちました。パイが地面に落ちた場合はもちろん食べられないので、ゲームボーイはすぐにバックパックを外して拾いました。しかし、トレイルの両側に誰もいないので、彼はトレイルでしか拾うことができません。ゲームボーイは通常、ゲームをプレイするために部屋にとどまるため、ゲームのアジャイルマスターですが、実際には運動神経が特に遅く、1秒あたり1メートル以内の範囲内でしか落下するパイを捕まえることができません。アイコンに示されているように、このトレイルの座標を指定します。
問題を単純化するために、次の期間にパイが0から10の11の位置に落ちると仮定します。当初、ゲームボーイは5位に立っていたため、最初の1秒間は、4、5、6の3つのポジションのうちの1つでしかパイを受け取ることができませんでした。ゲームボーイは最大で何個のパイを受け取ることができますか?(彼のバックパックが無限の数のパイを保持できると仮定して)入力
入力データには複数のグループがあります。データの各グループの最初の行は正の整数n(0 <n <100000)です。これは、n個のパイがこのパスに落ちたことを意味します。結果のn行では、各行に2つの整数x、T(0 <T <100000)があります。これは、パイが2番目のTで点xにあることを意味します。複数のパイが同じ秒の同じポイントに落ちる可能性があります。n = 0の場合、入力は終了します。
出力
入力データの各セットは、1行の出力に対応します。整数mを出力します。これは、ゲームボーイが最大でm個のパイを受け取る可能性があることを示します。
ヒント:この質問の入力データの量は比較的多いです。読み取りにはscanfを使用することをお勧めします。cinを使用するとタイムアウトになる場合があります。
サンプル入力
6 5 1 4 1 6 1 7 2 7 2 8 3 0サンプル出力
4
アイデア:
動的計画法の方程式:dp [i] [j] + = max(dp [i + 1] [j]、max(dp [i + 1] [j + 1]、dp [i + 1] [j-1] ));
i秒からj位置までに得られる最大の利点を表します
dp [i] [j]は、i番目の秒で位置jに落ちるパイの数を表します
実装コード:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[100001][20];//行表示时间,列表示位置
int main()
{
int i,j,k,n,x,t;
while(~scanf("%d",&n))
{
if(n==0)
break;
else
{
int e;
memset(dp,0,sizeof(dp));//初始化dp
while(n--)
{
scanf("%d%d",&x,&t);
dp[t][x+1]++;//这里都往前一位,
e=max(e,t);//得出最大的时间,这样也比用if来写更简洁
}
for(i=e;i>=0;i--)//时间由最大到0秒时
{
for(j=1;j<=11;j++)//位置由1到11
{
dp[i][j]+=max(dp[i+1][j],max(dp[i+1][j+1],dp[i+1][j-1]));//因为max是判断两者之间。我们要得出三个数中的最大,用两个max
}
}
printf("%d\n",dp[0][6]);
}
}
}