• 【NOIP2014提高组】飞扬的小鸟


    题目传送门:https://www.luogu.org/problem/show?pid=1941

    不难看出,此题为动态规划。

    我们用$f[i][j]$表示从第一行到达第i行第j列时点击屏幕的最少次数。

    不难推出,$f[i][j]=min(f[i-1][j+y[i-1]],f[i-1][j-k*x[i-1]]+k)$,其中k为整数,且$j+y[i-1]$,$j-k*x[i-1]$需在合法范围内,$(i,j)$不能是柱子。

    显然,这个转移的时间复杂度是$O(n*m^2)$的,只有70分,下面考虑进行优化。

    先考虑只向上跳的情况,对于转移$f[i][j]=f[i-1][j-2x[i-1]+2$,我们不妨设$f[i][1..j]和f[1..i][1..m]$已经全部是最优解,那么在考虑$f[i][j]$时,只需要判断$f[i-1][j-x[i-1]$和$f[i][j-x[i-1]$哪个更优即可。

    对于每一列,处理完向上跳的情况后,再处理向下滑行的状态。(我这里写挫了只剩下75,只能说数据实在太水)

    PS:对于鸟贴顶的情况,需要特殊判断。

    这样时间复杂度为$O(n*m)$。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define M 10100
     5 using namespace std;
     6 int f[M][1010]={0},b[M][1010]={0},n,m,k;
     7 int x[M]={0},y[M]={0};
     8 
     9 int get(int x,int y){
    10     if(y<=0) return f[0][0];
    11     if(y>m) return f[0][0];
    12     return f[x][y];
    13 }
    14 
    15 int main(){
    16     scanf("%d%d%d",&n,&m,&k);
    17     for(int i=0;i<n;i++) scanf("%d%d",x+i,y+i);
    18     for(int i=1;i<=k;i++){
    19         int p,l,h; scanf("%d%d%d",&p,&l,&h);
    20         for(int ii=h;ii<=m;ii++) b[p][ii]=i;
    21         for(int ii=0;ii<=l;ii++) b[p][ii]=i;
    22     }
    23     memset(f,1,sizeof(f)); 
    24     for(int i=1;i<=m;i++) f[0][i]=0;
    25     for(int i=1;i<=n;i++){
    26         for(int j=1;j<=m;j++){
    27             f[i][j]=min(f[i][j],get(i-1,j-x[i-1])+1);
    28         }
    29         for(int j=1;j<=m;j++)
    30             f[i][j]=min(f[i][j],get(i,j-x[i-1])+1);
    31         for(int j=m;j>=m-x[i-1];j--){
    32             f[i][m]=min(f[i][m],f[i-1][j]+1);
    33             f[i][m]=min(f[i][m],f[i][j]+1);
    34         }
    35             
    36         for(int j=1;j<=m;j++)
    37             f[i][j]=min(f[i][j],get(i-1,j+y[i-1]));
    38         for(int j=1;j<=m;j++) if(b[i][j])
    39         f[i][j]=f[0][0];
    40     }
    41     int minn=f[0][0];
    42     for(int i=1;i<=m;i++) minn=min(minn,f[n][i]);
    43     if(minn!=f[0][0]){
    44         printf("1
    %d
    ",minn);
    45         return 0;
    46     }
    47     for(int i=n-1;i>=0;i--){
    48         for(int j=1;j<=m;j++) if(f[i][j]!=f[0][0]){
    49             int ans=0;
    50             for(int ii=1;ii<=i;ii++) if(b[ii][m]) ans++;
    51             printf("0
    %d
    ",ans);
    52             return 0;
    53         }
    54     }
    55 }
  • 相关阅读:
    bound 很靠近0的mle
    order statistics 为什么3维要把6块加起来
    正态分布的来历
    互斥和独立
    平稳随机过程 会不会和随机过程矛盾呢?
    请问如何理解同一个随机过程,里面的两个随机变量的期望不同呢?
    bagging和boosting以及rand-forest
    arr = map(float,arr)输出问题
    lasso数学解释
    岭回归的数学解释
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/7751053.html
Copyright © 2020-2023  润新知