Uva 10912 Simple Minded Hashing (计数DP)


4th IIUC Inter-University Programming
Contest, 2005


H


Simple Minded Hashing


Input: standard input

Output: standard output


Problemsetter: Sohel Hafiz

All of you know a bit or two about hashing. It involves mapping an element into a numerical value using some mathematical function. In this problem we will consider a very ‘simple minded hashing’.
It involves assigning numerical value to the alphabets and summing these values of the characters.

For example, the string “acm” is mapped to 1 + 3 + 13 = 17. Unfortunately, this method does not give one-to-one mapping. The string “adl” also maps to 17 (1 + 4 + 12). This is called collision.

In this problem you will have to find the number of strings of length L, which maps to an integer S, using the above hash function. You have to consider strings
that have only lowercase letters in strictly ascending order.

Suppose L = 3 and S = 10, there are 4 such strings.

  1. abg
  2. acf
  3. ade
  4. bce

agb also produces 10 but the letters are not strictly in ascending order.

bh also produces 10 but it has 2 letters.

Input

There will be several cases. Each case consists of 2 integers L and S(0 < L, S < 10000). Input is terminated with 2 zeros.

Output

For each case, output Case #: where # is replaced by case number. Then output the result. Follow the sample for exact format. The result will fit in 32 bit signed integers.


Sample Input


Output for Sample Input


3 10

2 3

0 0


Case 1: 4

Case 2: 1

题意: 给你 m 和 n ,要你用找出 m 个依次 递增的数 (编号从 1 开始)(数字范围1---26),使他

们的和为 n ,输出满足条件的方案数。

思路:因为数字范围是 1---26 ,而题目要找的是m 个依次递增的数 ,所以可知 m 〉26 时  方案数  ans = 0;

同理我们可以知道   n 的最大值为 : 1+2+3+......+26 = 351     即  n 〉351 时  方案数 ans = 0;

所以我们只需讨论  m 〈 = 26  , n 〈= 351 时的情况 。

dp[ i ] [ j ][ k ]   表示 第 i 个数 取的是 k ,并且总和是 j 的方案数 。

即    dp[ i ] [ j ][ k ]  + =   dp[ i-1 ] [ j-k ][ t ] (0〈= t 〈 k) ;

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=405;

int n,m,cnt,dp[30][maxn][30];

void initial()
{
    memset(dp,0,sizeof(dp));
}

void solve()
{
    int ans=0;
    if(m>26 || n>351)  ans=0;
    else
    {
        dp[0][0][0]=1;
        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=n; j++)
                for(int k=1; k<=26; k++)
                {
                    int w=j-k;
                    if(w<0)  break;
                    for(int t=0;t<k;t++)  dp[i][j][k]+=dp[i-1][w][t];
                }
        }
        for(int i=1; i<=26; i++)  ans+=dp[m][n][i];
    }
    printf("Case %d: %d\n",++cnt,ans);
}

int main()
{
    while(scanf("%d %d",&m,&n)!=EOF)
    {
        if(m==0 && n==0)  break;
        initial();
        solve();
    }
    return 0;
}
时间: 2024-08-28 13:01:41

Uva 10912 Simple Minded Hashing (计数DP)的相关文章

UVA 10912 Simple Minded Hashing

题意就略了.刚一看被数据吓住了.看到字符要求严格递增.那么如果字串长大于26那必然方案数目为0:同时1+2+3....+24+25+26=351如果大于这个数也是不可能的 令dp[i][j][k]表示第i位为第j个字符和为K时的方案数目 那么 dp[i][j][k]=sum(dp[i-1][m][k-t])  {m<j;k-t尝试将第j位置为t} #include <map> #include <set> #include <list> #include <

UVA10912 - Simple Minded Hashing(dp)

题目链接 题目大意:给你L和S,把小写的26个字母定义为1-26,然后要求找出有多少个这样的字符串,首先要满足严格的递增顺序(a<b<c),并且要有L个字母,而且和为S. 解题思路:这提和之前做过的题目很想,但是不一样的地方在于这题的字母选择是有要求的,不仅仅是和要等于S,还需要保持递增,也就是之前你用过的不能再用的意思.而且这题的范围给的有点大了,其实只有26个字母,最大的和只可能是351.不符合这些的都可以直接输出0.然后就是dp[n][num][sum]:已经放到第n个位置了,这个位置的

Uva 10401 Injured Queen Problem ( 计数DP)

Problem I Injured Queen Problem Input: standard input Output: standard output Time Limit: 6 seconds Memory Limit: 32 MB Chess is a two-player board game believed to have been played in India as early as the sixth century. However, in this problem we

uva 11584 Partitioning by Palindromes 线性dp

// uva 11584 Partitioning by Palindromes 线性dp // // 题目意思是将一个字符串划分成尽量少的回文串 // // f[i]表示前i个字符能化成最少的回文串的数目 // // f[i] = min(f[i],f[j-1] + 1(j到i是回文串)) // // 这道题还是挺简单的,继续练 #include <algorithm> #include <bitset> #include <cassert> #include <

UVA - 825Walking on the Safe Side(dp)

题目: UVA - 825Walking on the Safe Side(dp) 题目大意:给出一个n * m的矩阵,起点是1 * 1,终点是n * m,这个矩阵上有些点是不可以经过的,要求从起点到终点距离最短,并且不能走那种不能走的点,一共有多少种方式. 解题思路:要求路径最短的话,每个点要不向右走,要不向下走.dp[i][j] = dp[i][j + 1] + dp[i + 1][j]:当这个点不能通过,dp[i][j] = 0:这个坑点在样例输入,不一定是规范的输入,可能两个数字之间很多

HDU4815/计数DP

题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=4815] 简单说一下题意: 有n道题,每到题答对得分为a[ i ],假如A不输给B的最小概率是P,那么A最少要得到多少分. 解题过程: 假设有n道题,每个题有两个状态,胜或者败,假设达到某个分数m有k(计数DP)种方式,那么最后是这个分数的概率是k/pow(2,n).那么A不输给B的概率就是小于等于m的分数的概率和. #include<bits/stdc++.h> const int maxn =

uva 11361 Investigating Div-Sum Property 数位dp

// uva 11361 Investigating Div-Sum Property 数位dp // // 题目大意: // // 给你一个整数a和一个整数b,问在[a,b]范围内,有多少个自身被k整除并且 // 各位数之和也能被k整除.比如k = 7 ,322满足条件,因为332能被整除7,并 // 3 + 2 + 2 = 7 也能被7整除 // // 解题思路: // // 求一个区间的题目,这类题目,往往可以转化为不超过x的f(x).则最后要求 // 的就是f(b) - f(a-1).如

[sdut]2879计数dp……或者递推

第五届省赛C:colourful cupcakes N=60. 天真如我,居然在考虑搜索的算法/(ㄒoㄒ)/~~三叉树……3^60=10^24+……不计算考虑复杂度都是耍流氓>_< 再算了一下,感觉O(N^4)可以试试,60^4=10^8+……但是毕竟最差的情况嘛>_<,再看一下题解果然是4重循环的……计数……dp……(想到之前坚信的搜索不禁(*/ω\*)) 中间看到了一个三次动规六个方程的算法. 做麻烦了. 学长思路好快. #include<iostream> #in

HDU4901 The Romantic Hero 计数DP

2014多校4的1005 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4901 The Romantic Hero Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 393    Accepted Submission(s): 150 Problem Description There i