zoukankan      html  css  js  c++  java
  • Codeforces 474D Flowers 动态规划法

    话说好久没写算法代码了,工作了有点忙的了。只是算法始终是我的挚爱,故此还是尽量抽时间和挚爱来个约会。


    Codeforces的题目是最适合练手的了,以下是一道不算难的动态规划法题目。先上题:

    D. Flowers

    time limit per test1.5 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    We saw the little game Marmot made for Mole’s lunch. Now it’s Marmot’s dinner time and, as we all know, Marmot eats flowers. At every dinner he eats some red and white flowers. Therefore a dinner can be represented as a sequence of several flowers, some of them white and some of them red.

    But, for a dinner to be tasty, there is a rule: Marmot wants to eat white flowers only in groups of size k.

    Now Marmot wonders in how many ways he can eat between a and b flowers. As the number of ways could be very large, print it modulo 1000000007 (109 + 7).

    Input
    Input contains several test cases.

    The first line contains two integers t and k (1 ≤ t, k ≤ 105), where t represents the number of test cases.

    The next t lines contain two integers ai and bi (1 ≤ ai ≤ bi ≤ 105), describing the i-th test.

    Output
    Print t lines to the standard output. The i-th line should contain the number of ways in which Marmot can eat between ai and bi flowers at dinner modulo 1000000007 (109 + 7).

    Sample test(s)
    input
    3 2
    1 3
    2 3
    4 4
    output
    6
    5
    5
    Note
    For K = 2 and length 1 Marmot can eat (R).
    For K = 2 and length 2 Marmot can eat (RR) and (WW).
    For K = 2 and length 3 Marmot can eat (RRR), (RWW) and (WWR).
    For K = 2 and length 4 Marmot can eat, for example, (WWWW) or (RWWR), but for example he can’t eat (WWWR).

    算法思路:
    1 逐步添加计算的,那么就是逐步填表;
    2 设tbl[]为动态规划的表格。 那么每新增第i个表格的时候。新格子仅仅能填写R或者W。填写R的时候就相当于是有tbl[i-1]种填法,由于最后一个格子定了,仅仅能填写R,假设填写W的时候呢?那就是有tbl[i-k]中写法了,由于依据题意。填写了W之后,i个格子之前的全部k个格子都仅仅能填写W,由于W要么不出现,要么就仅仅能k个W连着出现。
    故此终于得到的状态转换公式:
    tbl[i] = tbl[i-1] + tbl[i-k];
    3 可是本题目略微进了一步,由于须要求区间的和值,哇。一看好像要使用线段树的节奏,事实上不须要使用线段树,仅仅须要使用个小算法就能够。高手嘛。小算法自然顺手粘来,仅仅要添加一个sum[]数组,然后计算sum[i] = tbl[0 – i]的和就能够使用sum[i] - sum[j-1]计算[j, i]之间的和值啦。当然计算sum[i] = tbl[0 – i]也是有点技巧的,看代码就知道了。
    4 最后还添加点难度,就是会溢出,只是题目要求了求1e9 +7的Mod值

    上代码:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        const int MOD = (int)1e9 + 7;
        const int MAX_M = (int)1e5 + 1;
        int t, k;
        scanf("%d %d", &t, &k);
    
        int tbl[MAX_M] = {};
        for (int i = 0; i < k; i++)
        {
            tbl[i] = 1;
        }
    
        for (int i = k; i < MAX_M; i++)
        {
            tbl[i] = tbl[i - 1] + tbl[i - k];
            tbl[i] %= MOD;
        }
    
        int sum[MAX_M] = {};
        sum[0] = 0;
        for (int i = 1; i < MAX_M; i++)
        {
            sum[i] = sum[i - 1] + tbl[i];
            sum[i] %= MOD;
        }
    
        int a, b;
        for (int i = 0; i < t; i++)
        {
            scanf("%d %d", &a, &b);
    
            printf("%d
    ", (sum[b] - sum[a - 1] + MOD) % MOD);
        }
    
        return 0;
    }
  • 相关阅读:
    NPIV介绍
    PowerShell随笔2_分支 选择 循环 特殊变量
    socket编程原理
    Linux查看物理CPU个数、核数、逻辑CPU个数
    Markdown 使用指南
    Linux Socket
    YoutubeAPI使用
    Youtube API数据类型
    Linux wpa_cli 调试方法
    linux网络编程
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7288941.html
Copyright © 2011-2022 走看看