zoukankan      html  css  js  c++  java
  • C. The Hard Work of Paparazzi dp

    C. The Hard Work of Paparazzi dp

    题目大意:

    给你一个大小为 (r*r) 大小的矩阵,初始你在位置 ((1,1)) 这个点,有 (n) 个点,对于第 (i) 个人来说,它只在 (t_i) 时刻处于 ((x_i,y_i)) 这个位置,如果此时你也在这个位置,那么你就可以收获到这个点,如果你此时在 ((x,y)) 这个位置,那么经过 (t = abs(x-x_i)+abs(x-y_i)) 时间,你可以到达 ((x_i,y_i)) 这个位置,问你最多可以收获多少个点,保证 (t_i<t_{i+1}<=1000000)(1<=x_i,y_i<=r<=500) (n<=100000)

    题解:

    • 碰到 (dp) 这种题目,首先要找到一个合适的 (dp) 的定义
    • (dp[i]) 表示在 (t_i) 时刻,位置 ((x_i,y_i)) 的最优解
    • 因为保证 (t_i<t_{i+1}) ,注意是严格小于
    • 所以对于每一个时刻最多只有一个点
    • 那么,因为 (r<=500) ,所以如果时刻相差大于等于 (1000) 就一定可以转移
    • 所以,我最多只需要枚举前面1000个时间点
    • 复杂度是 (O(n*1000))
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+10;
    typedef long long ll;
    int dp[maxn],que[maxn],x[maxn],y[maxn],t[maxn];
    /*
     * dp[i] 表示在 ti 时刻,位置 (xi,yi) 的最优解
     */
    int main(){
        int r,n;
        scanf("%d%d",&r,&n);
        for(int i=1;i<=n;i++) scanf("%d%d%d",&t[i],&x[i],&y[i]);
        memset(dp,0xef,sizeof(dp));
        x[0] = y[0] = 1,dp[0] = 0,t[0] = 0;
        int el = 1,er = 1,maxs = -1e9,ans = 0;
        que[el] = 0;
        for(int i=1;i<=n;i++){
            while(el<=er&&t[i]-t[que[el]]>=1000) maxs = max(maxs,dp[que[el]]),el++;
            dp[i] = max(dp[i],maxs+1);
            for(int j=el;j<=er;j++){
                int id = que[j],val = abs(x[i]-x[id])+abs(y[i]-y[id]);
                if(t[i]-t[id]>=val) dp[i] = max(dp[i],dp[id]+1);
            }
    //        printf("i = %d dp[%d]=%d el = %d er = %d maxs = %d
    ",i,i,dp[i],el,er,maxs);
            que[++er] = i;
            ans = max(ans,dp[i]);
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    通过ifconfig命令分析
    网络协议初探
    商品详情页面属性价格显示其对应价格
    ecshop属性 {$goods.goods_attr|nl2br} 标签的赋值相关
    CI模板中如何引入模板
    jQuery取得/设置select的值
    ecshop如何增加多个产品详细描述的编辑器
    获取span里面的值(特殊情况下 )
    一个页面有相同ID元素的情况分析
    表单辅助函数-form_open()
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14546231.html
Copyright © 2011-2022 走看看