zoukankan      html  css  js  c++  java
  • cf 1453F. Even Harder (DP)

    题目链接: 传送门

    思路:

    显然,这是一个DAG,而且1 2 3 ... n-1 n 是该图的一个拓扑序。

    定义f(i,j)表示 唯一能到达 i 的路径, 满足 a[k] + k <= j , k∈[1,i) , 换言之 i 表示之前的点能覆盖到的标号最大的点 <= j . 

    f(i,j+aj) <-- f(j,i-1) + cnt, cntj 表示需要置零的点的数目,j∈[1,i-1) , 由于 f(j,i-1) 的定义,那么[1,j)中所有能到达i 的点已经被删掉了,那么 还需要处理 (j, i) 的点,因此cntj = ∑i-1k=j+1 ( a[k] + k >= i)

    该状态及转移方程能表示每种路径的唯一性,能避免转移时 既要考虑前面的点 又要考虑后面的点的后效性。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 typedef unsigned long long uLL;
     5 typedef pair<int,int> pii;
     6 typedef pair<LL,LL> pLL;
     7 typedef pair<double,double> pdd;
     8 const int N=3e3+5;
     9 const int M=1e7+5;
    10 const int inf=0x3f3f3f3f;
    11 const LL mod=998244353;
    12 const double eps=1e-8;
    13 const long double pi=acos(-1.0L);
    14 #define ls (i<<1)
    15 #define rs (i<<1|1)
    16 #define fi first
    17 #define se second
    18 #define pb push_back
    19 #define eb emplace_back
    20 #define mk make_pair
    21 #define mem(a,b) memset(a,b,sizeof(a))
    22 LL read()
    23 {
    24     LL x=0,t=1;
    25     char ch;
    26     while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
    27     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
    28     return x*t;
    29 }
    30 int a[N],f[N][N];
    31 int main()
    32 {
    33     int T=read();
    34     while(T--)
    35     {
    36         int n=read();
    37         for(int i=1;i<=n;i++) a[i]=read();
    38         for(int i=2;i<=n;i++)
    39             for(int j=1;j<=n;j++)
    40                 f[i][j]=inf;
    41         for(int i=1;i<=n;i++) f[1][i]=0;
    42         for(int i=2;i<=n;i++)
    43         {
    44             int cnt=0;
    45             for(int j=i-1;j;j--)
    46             {
    47                 if(j+a[j]<i) continue;
    48                 f[i][j+a[j]]=min(f[i][j+a[j]],f[j][i-1]+cnt);
    49                 cnt++;
    50             }
    51             for(int j=2;j<=n;j++)
    52                 f[i][j]=min(f[i][j],f[i][j-1]);
    53         }
    54         printf("%d
    ",f[n][n]);
    55     }
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    LightOj 1016
    uva 127 "Accordian" Patience 简单模拟
    hdu 1180 诡异的楼梯 BFS + 优先队列
    UVALive 3907 Puzzle AC自动机+DP
    HDU 4001 To Miss Our Children Time DP
    HDU 4000 Fruit Ninja 树状数组
    hdu_1021_Fibonacci Again_201310232237
    hdu_1005_Number Sequence_201310222120
    hdu_1029-Ignatius and the Princess IV_201310180916
    hdu_1020_Encoding_201310172120
  • 原文地址:https://www.cnblogs.com/DeepJay/p/14116025.html
Copyright © 2011-2022 走看看