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
  • 相关阅读:
    .net core 支付宝,微信支付 一
    .net core AES加密解密及RSA 签名验签
    .net core 使用webservice
    .net core 使用X509 私钥加密请求
    .net core mysql entity映射时字符串被截断
    VS 2017 RC .net core ef+ MySql 出现错误
    IdentityServer4 简单使用,包括api访问控制,openid的授权登录,js访问
    iOS面试题之内存管理
    iOS之tableView性能优化/tableView滑动卡顿?
    iOS面试题之runloop
  • 原文地址:https://www.cnblogs.com/FOXYY/p/7675426.html
Copyright © 2011-2022 走看看