天天写算法之免费馅饼

原题链接

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

那么好了,假设你完成了这个bug,从这个坑里出来了,那么来看第二个坑,第一次的循环一定不能不管dp【1】【5】 dp【1】【6】 dp【1】【4】,因为这一行直接决定了,你是否用到了题目给的条件,不然直接gg。其他位置是不可能出现值的,即使那个地方a【1】【i】不为0,但是f一定为0.
上代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值