zoukankan      html  css  js  c++  java
  • Hdu 5459 Jesus Is Here (2015 ACM/ICPC Asia Regional Shenyang Online) 递推

    题目链接:

      Hdu 5459 Jesus Is Here

    题目描述:

      s1 = 'c', s2 = 'ff', s3 = s1 + s2; 问sn里面所有的字符c的距离是多少?

    解题思路:

      直觉告诉我们,sn肯定由sn-1与sn-2推导出来的。然后呢,我们可以看出 n%2==1 的时候 sn-1 与 sn-2 由 ffff 衔接起来的,n%2==0 的时候,sn-1 与 sn-2由 ff 衔接起来的。告诉队友后,队友就把这个当成重要依据推啊,推啊!!到最后感觉丢队友自己看药丸,放弃02回来和队友一起看,发现这样想脑洞太大,完全错误.......真是真是可怜,这个锅我接!!

      我们先设定len[i], num[i], sum[i], ans[i]分别是:si的长度,si中c的数目,si中c的下标和,si中所有字符c的距离。

      则有:

        len[i]   = len[i-1] + len[i-2];

        num[i] = num[i-1] + num[i-2];

        sum[i] = sum[i-1] + sum[i-2] + len[i-2] * num[i-1];

        ans[i]  = ans[i-1] + ans[i-2] + (len[i-2] * num[i-2] - sum[i-2]) * num[i-1] + num[i-2] * sum[i-1];

      对于len,num很容易理解,就是斐波那契数列。

      sum[i] = sum[i-1] + sum[i-2] 很容易理解,由于si-1在si-2后面,所以对于每一个si-1里面的c来说下标都加上了len[i-2], 然后很自然的就加上 len[i-2] * num[i-1];

      对于ans[i]来说,ans[i]  = ans[i-1] + ans[i-2] 很容易理解,然后还有 si-1 与 si-2 里面的c的距离没有加上。我们把 si 看成两部分,以衔接处为分割线,前部分的贡献值为:(len[i-2] * num[i-2] - sum[i-2]) * num[i-1] ,对于后半部分的每个c来说,前半部分的贡献是相同的,都是前半部分中的每个c的坐标到分割线的位置。后半部分的贡献值为 num[i-2] * sum[i-1],正好与前半部分相反;

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long LL;
     7 const LL maxn = 201320;
     8 const LL mod = 530600414;
     9 LL ans[maxn], len[maxn], sum[maxn], num[maxn];
    10 int main ()
    11 {
    12     LL t, n;
    13     scanf ("%lld", &t);
    14     len[1] = sum[1] = num[1] = 1;
    15     len[2] = 2;
    16     sum[2] = num[2] = 0;
    17     for (int i=3; i<maxn; i++)
    18     {
    19         len[i] = (len[i-1] + len[i-2]) % mod;
    20         num[i] = (num[i-1] + num[i-2]) % mod;
    21         sum[i] = ((sum[i-1] + sum[i-2]) % mod + num[i-1] * len[i-2] % mod) % mod;
    22         ans[i] = ((ans[i-1] + ans[i-2]) % mod + (num[i-2]*len[i-2]-sum[i-2]) % mod*num[i-1] % mod + num[i-2] * sum[i-1] % mod) % mod;
    23     }
    24     for (LL i=1; i<=t; i++)
    25     {
    26         scanf ("%lld", &n);
    27         printf ("Case #%lld: %lld
    ", i, ans[n]);
    28     }
    29     return 0;
    30 }

      

    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
    Fliptile 开关问题 poj 3279
    Face The Right Way 一道不错的尺取法和标记法题目。 poj 3276
    Aggressive cows 二分不仅仅是查找
    Cable master(二分题 注意精度)
    B. Pasha and String
    Intervals poj 1201 差分约束系统
    UITextField的快速基本使用代码块
    将UIImage转换成圆形图片image
    color转成image对象
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4829425.html
Copyright © 2011-2022 走看看