您的位置:首页 > 其它

天天写算法之免费馅饼

2018-03-22 10:06 274 查看
点击打开链接原题链接

这个题坑真的很多,先说的确是dp问题,为什么会想到dp呢,因为这一个chapter都是dp。设a[i][j]为第i秒的j位置掉下的馅饼数量,f[i][j]为第i秒在j位置接馅饼最多可以接到的最多馅饼数量。由于每秒只能移动一个位置:f[i][j] = max(f[i - 1][j - 1], f[i - 1][j], f[i - 1][j + 1]) + a[i][j];得到了这个式子只是第一步。
#include <iostream>
#include <iomanip>
#include<queue>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<iomanip>
#include<string.h>
#include<sstream>
#include<string>
//¶¨Ò庯Êý¶Î
#define repf(i,a,b) for(int i =(a);i<(b);i++)
#define repfe(i,a,b) for(int i =(a);i<=(b);i++)
using namespace std;
const int inf = -1000;
int data[100001][12];
int dp[100001][12];

int main() {
int num,position,t,Max,MaxT = 0,tempDp = -1;

while(cin>>num&&num!=0)
{
memset(data,0,sizeof(data));
repfe(i,1,num)
{
cin>> position>> t ;
if(t>MaxT)
{
MaxT = t ;
}
data[t][position] ++;

}
memset(dp,0,sizeof(data));
dp[1][4] = data[1][4];
dp[1][5] = data[1][5];
dp[1][6] = data[1][6];
repfe(i,2,MaxT)
{
repf(j,0,11)
{
tempDp = -1 ;
tempDp = max(tempDp,dp[i-1][j]);
if(j<10)
tempDp = max(tempDp,dp[i-1][j+1]);
if(j>0)
tempDp = max(tempDp,dp[i-1][j-1]);
dp[i][j] = tempDp + data[i][j];
//  cout << j <<" " << i <<" "<<dp[j][i]<<endl;
}
}

int res = 0 ;
repf(i,0,12)
{
if(dp[MaxT][i]>res)
{
res = dp[MaxT][i];
}
}
cout <<res <<endl;

}

return 0;
}


开始入坑。题目给的position和t是先p后
9752
t这样的顺序进行的。这样就很容易诱导我们创建一个【p】【t】的二维数组。从而我们很有可能循环的时候寻找每个位置,所有时刻的最佳值。但很明显我们上边那个式子是相悖的。因为我们是以位置为先导,因此我们需要找到的是位置的先后关系,而不是时间i与i-1的先后关系。

那么好了,假设你完成了这个bug,从这个坑里出来了,那么来看第二个坑,第一次的循环一定不能不管dp【1】【5】 dp【1】【6】 dp【1】【4】,因为这一行直接决定了,你是否用到了题目给的条件,不然直接gg。其他位置是不可能出现值的,即使那个地方a【1】【i】不为0,但是f一定为0.上代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: