• 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;
    }
    
  • 相关阅读:
    PHP之readdir()函数
    PHP之compact()函数
    scanf_s
    GitHub高级搜索
    负载均衡算法
    git操作
    SpringBoot引入监听器
    Redis高可用
    50个常用sql语句 网上流行的学生选课表的例子
    Mysql优化策略
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14546231.html
Copyright © 2020-2023  润新知