zoukankan      html  css  js  c++  java
  • xtuoj 1233 coins(dp)

    Coins

    Accepted : 120   Submit : 305
    Time Limit : 1000 MS   Memory Limit : 65536 KB

    Coins

    Problem Description:

    Duoxida buys a bottle of MaiDong from a vending machine and the machine give her n coins back. She places them in a line randomly showing head face or tail face on. And Duoxida wants to know how many situations that m continuous coins head face on among all possible situations. Two situations are considered different if and only if there is at least one position that the coins' faces are different.

    Input

    The first line contains a integer T(no more than 20) which represents the number of test cases.

    In each test case, a line contains two integers n and m.(\(0 < m \le n \le 10^6\))

    Output

    For each test case, output the result modulo \(10^9+7\) in one line.

    Sample Input

    2
    4 2
    5 2

    Sample Output

    8
    19


    Source

    XTU OnlineJudge 

    这题的话dp起来还是比较简单的。

    dp[0][i]代表不满足情况下长度为i的硬币串数量。

    dp[1][i]代表满足情况下长度为i的硬币串数量。

    对于i<m 显然所有状态都不满足连续m个硬币正面朝上,d[0][i]=2^i,dp[1][i]=0;

    对于i=m 那么只有一种情况连续m个硬币正面朝上,d[0][i]=2^i-1,dp[1][i]=1;

    对于i>m,对于满足的情况,考虑到所有状况并且为了避免状况重复,他可以从i-1长度下满足的情况下,在i位置添加一个任意面得到i长度下满足的情况;也能从i-m-1长度的不满足的情况下,在其之后添加一个反面朝上,然后添加m个正面朝上来得到i长度下满足的情况,注意这样的情况是最长长度为m,并且连续的长度最后一位在i位置,与前一种方式的出来的情况没有重复部分。而且两者包含所有的满足的情况,所以,dp[1][i]=dp[1][i-1]*2+dp[0][i-m-1]。不满足的情况即为所有状态减去满足的情况:dp[0][i]=2^i-dp[1][i]。因此此题只要O(n)即能dp得出答案。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring> 
     4 #define clr(x) memset(x,0,sizeof(x))
     5 #define LL long long 
     6 #define MOD (1000000007)
     7 using namespace std;
     8 LL dp[2][1000010];
     9 LL pow[1000010];
    10 int main()
    11 {
    12     int n,m;
    13     int T;
    14     scanf("%d",&T);
    15     pow[0]=1;
    16     for(int i=1;i<=1000000;i++)
    17     {
    18         pow[i]=(pow[i-1]*2)%MOD;
    19     }
    20     while(T--)
    21     {
    22         scanf("%d%d",&n,&m);
    23         for(int i=0;i<=m;i++)
    24         {
    25             dp[1][i]=0;
    26             dp[0][i]=pow[i];
    27         }
    28         dp[1][m]=1;
    29         dp[0][m]=pow[m]-dp[1][m];
    30         for(int i=m+1;i<=n;i++)
    31         {
    32             dp[1][i]=(dp[1][i-1]*2+dp[0][i-m-1])%MOD;
    33             dp[0][i]=((pow[i]-dp[1][i])%MOD+MOD)%MOD;
    34         }
    35         printf("%lld
    ",dp[1][n]);
    36     }
    37     return 0;
    38  } 
    dp
  • 相关阅读:
    育碧-彩虹六号如何绑定二次验证码/两步验证/身份验证?
    leetcode刷题-95/96/98
    leetcode刷题-94二叉树的中序遍历
    leetcode刷题-93复原IP地址
    leetcode刷题-91解码方法
    leetcode刷题-90子集 II
    leetcode刷题-89格雷编码
    leetcode刷题-88.合并两个有序数组
    leetcode刷题-86分隔链表
    leetcode刷题-82.删除排序链表中的重复元素 II
  • 原文地址:https://www.cnblogs.com/wujiechao/p/6860239.html
Copyright © 2011-2022 走看看