zoukankan      html  css  js  c++  java
  • BZOJ[1925] [Sdoi2010]地精部落

    很难理解的一个DP

    首先先说明两个状态数组,f[i][j]表示当前序列的长度为i,最后一位是第j小,且第i位为山谷的方案数,同理g[i][j]表示f[i][j]表示当前序列的长度为i,最后一位是第j小,且第i位为山峰的方案数;

    那么f就是能从g转移过来,

    那么f[i][j]就等于g[i-1][k] (j<=k<=i-1);然后考虑优化,可以想象把整段山脉倒过来,那么f[i][j]与g[i][i-j+1]的方案书是一样的,那么f[i][j]就等于f[i-1][k](1<=k<=i-j);

    然后我一直不理解的是,这里的j只是表示一个相对的大小关系,当他联系到具体的数字的时候,不用考虑第j小的数字到底要选哪个么? 是不是要乘一个 j... 什么的东西,

    其实这个相对关系可以说是唯一的,他只是表示满足当前大小关系的状态的方案数,而不是满足这种关系具体有多少可能,当转移到最后的n的时候,第j小时哪一个数字就是确定的,然后从之前转移过来的每一种状态也都就是确定的,也就是之前说的唯一的;

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <iostream>
     6 #include <algorithm>
     7 using namespace std;
     8 typedef long long LL;
     9 int n;
    10 LL mod;
    11 LL f[3][4300];
    12 int main(){
    13 //    freopen("a.in","r",stdin);
    14     scanf("%d%lld",&n,&mod);
    15     f[1][1]=1; int rol=0;
    16     for(int i=2;i<=n;i++){
    17         memset(f[rol],0,sizeof(f[rol]));
    18         LL sum=0; 
    19         for(int j=i-1;j>=1;j--){
    20             sum=(sum+f[rol^1][i-j])%mod;
    21 //            cout<<"sim== "<<sum<<endl;
    22             f[rol][j]=sum;
    23         }
    24         rol^=1;
    25     }
    26     LL ans=0;
    27     for(int i=1;i<=n;i++){
    28         ans=(ans+f[rol^1][i])%mod;
    29     }
    30     ans=(ans*2)%mod;
    31     cout<<ans<<endl;
    32 }
    View Code
  • 相关阅读:
    poj 1743 Musical Theme 后缀数组
    poj 1743 Musical Theme 后缀数组
    cf 432D Prefixes and Suffixes kmp
    cf 432D Prefixes and Suffixes kmp
    hdu Data Structure? 线段树
    关于position和anchorPoint之间的关系
    ios POST 信息
    CALayers的代码示例
    CALayers详解
    ios中得sqlite使用基础
  • 原文地址:https://www.cnblogs.com/FOXYY/p/7675426.html
Copyright © 2011-2022 走看看