lightoj-1145 - Dice (I)(dp计数)

1145 - Dice (I)
PDF (English) Statistics Forum
Time Limit: 2 second(s) Memory Limit: 32 MB
You have N dices; each of them has K faces numbered from 1 to K. Now you have arranged the N dices in a line. You can rotate/flip any dice if you want. How many ways you can set the top faces such that the summation of all the top faces equals S?

Now you are given N, K, S; you have to calculate the total number of ways.

Input
Input starts with an integer T (≤ 25), denoting the number of test cases.

Each case contains three integers: N (1 ≤ N ≤ 1000), K (1 ≤ K ≤ 1000) and S (0 ≤ S ≤ 15000).

Output
For each case print the case number and the result modulo 100000007.

Sample Input
Output for Sample Input
5
1 6 3
2 9 8
500 6 1000
800 800 10000
2 100 10
Case 1: 1
Case 2: 7
Case 3: 57286574
Case 4: 72413502
Case 5: 9

解题思路:定义dp[i][j] 表示摇了n个骰子,总和为j。

不难发现:dp[i][j] = dp[i-1][j-1] + ……+dp[i-1][max(0,j-k)]; 将所有i-1 层中能达到j的次数加起来 就是邀n个骰子能到j的次数

则 dp[i][j-1] = dp[i-1][j-2]+……+dp[i-1][max(0,j-k-1)];

合并得dp[i][j] = dp[i][j-1]+dp[i-1][j-1]-dp[i-1][max(0,j-k-1)];

因为要加mod ,所以式子写成dp[i][j] = (dp[i][j-1]+dp[i-1][j-1]-dp[i-1][max(0,j-k-1)]+mod)%mod;ps: 里面+mod 是因为可能出现减数的mod 大于前面2个的情况 此时要+mod 把他纠正为正数。

以上的状态转移足够解决这个问题,但是题目给的内存只有32MB 。 这样写会超限。

我们在分析下会发现,其实每次计算都只需要i-1,i 这两个状态,那么我们定义一个dp[2][j] 来滚动存储就可以了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int mod = 100000007;
long long dp[2][15010];

int main(){
    int T,n,k,s;

    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        scanf("%d%d%d",&n,&k,&s);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=k;i++) dp[1][i] = 1;

        for(int i=2;i<=n;i++){
            for(int j=1;j<=s;j++){
                dp[i%2][j] = (dp[i%2][j-1]+dp[(i+1)%2][j-1] - dp[(i+1)%2][max(0,j-k-1)]+mod)%mod;
            }
            //cout<<dp[i][s]<<endl;
        }
        printf("Case %d: %lld\n",t,dp[n%2][s]);
    }

}
时间: 2024-11-13 06:56:40

lightoj-1145 - Dice (I)(dp计数)的相关文章

ZOJ3380- Patchouli&#39;s Spell Cards(概率DP+计数)

Patchouli's Spell Cards Time Limit: 7 Seconds      Memory Limit: 65536 KB Patchouli Knowledge, the unmoving great library, is a magician who has settled down in the Scarlet Devil Mansion (紅魔館). Her specialty is elemental magic employing the seven ele

动态规划(DP计数):HDU 5116 Everlasting L

Matt loves letter L. A point set P is (a, b)-L if and only if there exists x, y satisfying: P = {(x, y), (x + 1, y), . . . , (x + a, y), (x, y + 1), . . . , (x, y + b)}(a, b ≥ 1) A point set Q is good if and only if Q is an (a, b)-L set and gcd(a, b)

HDU 4055 The King’s Ups and Downs(DP计数)

题意:国王的士兵有n个,每个人的身高都不同,国王要将他们排列,必须一高一矮间隔进行,即其中的一个人必须同时高于(或低于)左边和右边.问可能的排列数.例子有1千个,但是最多只算到20个士兵,并且20个的情况的答案已给出. 思路:是此题HDU 4055 Number String(DP计数) 的简单版,所以看此题解就行了.数量较小,可以预先算出来.要同时考虑 <><>和><><这样的两种情况. 1 #include <iostream> 2 #inc

uva 1350 - Pinary(dp+计数)

题目链接:uva 1350 - Pinary 题目大意:给出n,输出第n给Pinary Number,Pinary Number为二进制数,并且没有连续两个1相连. 解题思路:dp[i]表示到第i位有dp[i]种,于是给定n,一层循环判断dp[i]≤n的话,就输出1,并且n减掉dp[i],注意输出0的时候,不能输出前导0. #include <cstdio> #include <cstring> typedef long long ll; const int N = 50; ll

LightOJ - 1248 Dice (III) 期望 + dp

题目大意:给出一个n面的色子,问看到每个面的投掷次数期望是多少 解题思路:水题啊,竟然被卡了那么久,也是醉了,给题目所给的那个样例误导了...不怪那个 怪自己太弱了,还得继续训练啊... 设dp[i]表示扔到i个不同面的期望,那么 dp[i + 1] = i / n * dp[i + 1] + (n - i) / n * dp[i] + 1 整理得 dp[i + 1] = n / (n - i) + dp[i] + 1 #include<cstdio> #define maxn 100010

lightoj 1248-G - Dice (III) (概率dp)

题意:给你n个面的骰子,问扔出所有面的期望次数. 虽然这题挺简单的但还是要提一下.这题题目给出了解法. E(m)表示得到m个不同面的期望次数. E(m+1)=[((n-m)/n)*E(m)+1]+(m/n)*E(m+1); 想必((n-m)/n)*E(m)+1这个很好理解吧,当得到m个面时他有((n-m)/n)的概率得到没得到过的面 而(m/n)*E(m+1)不太好理解为什么,其实题目已经给出解释了,如果他有(m/n)的概率出到不同 面也有1-(m/n)的概率得到相同面,所以直接加上((n-m)

Throwing Dice(概率dp)

C - Throwing Dice Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu LightOJ 1064 uDebug Description n common cubic dice are thrown. What is the probability that the sum of all thrown dice is at least x? Input Input starts wit

Lightoj 1044 - Palindrome Partitioning (DP)

题目链接: Lightoj  1044 - Palindrome Partitioning 题目描述: 给一个字符串,问至少分割多少次?分割出来的子串都是回文串. 解题思路: 先把给定串的所有子串是不是回文串处理出来,然后用dp[i] 表示 从起点到串i的位置的最少分割次数,然后结合处理出来的回文串转移一下即可! 还是好蠢哦!自己竟然感觉是一个区间DP,但是n又那么大,完全不是区间DP的作风啊! 1 #include <cmath> 2 #include <cstdio> 3 #i

lightoj 1381 - Scientific Experiment dp

1381 - Scientific Experiment Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lightoj.com/volume_showproblem.php?problem=1381 Description John wants to be a scientist. A first step of becoming a scientist is to perform experiment. John has de