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 <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
#define MAXN 360
#define MAXD 30
int l,s;
int tab[MAXD];
int dp[MAXD][MAXD][MAXN];
void init()
{
    memset(dp,0,sizeof(dp));
    memset(tab,0,sizeof(tab));
    for (int i=1; i<=26; i++) tab[i] = tab[i-1] + i;
    for (int i=1; i<=26; i++) dp[1][i][i] = 1;
    for (int i=2; i<=26; i++)
        for (int j=i; j<=26; j++)
            for (int s=tab[i]; s<=351; s++)
    {
        for (int k=1; k<j && k<s; k++)
            dp[i][j][s] += dp[i-1][k][s-j];
    }
}
int slove()
{
    int ans = 0;
    for (int i=l; i<=26; i++)
        ans += dp[l][i][s];
    return ans;
}
int main()
{
    init();
    int kase = 1;
    while (scanf("%d%d",&l,&s)!=EOF)
    {
        if (l == 0 && s==0) break;
        if (l > 26 || s > 351)
        printf("Case %d: %d\n",kase++,0);
        else printf("Case %d: %d\n",kase++,slove());
    }
    return 0;
}
时间: 2024-08-15 19:04:45

UVA 10912 Simple Minded Hashing的相关文章

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 usi

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 12253 - Simple Encryption(dfs)

题目链接:uva 12253 - Simple Encryption 题目大意:给定K1,求一个12位的K2,使得KK21=K2%1012 解题思路:按位枚举,不且借用用快速幂取模判断结果. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const ll ite=(1<<20)-1; ll N; /* l

uva 10014 Simple calculations

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=955 根据递推公式推倒出a1的公式. a1=(n*a0+an+1-2*(n*c1+(n-1)*c2+...+cn))/(n+1); 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm>

UVA 10994 Simple Addition

感觉这个一定要记下来涨教训啊.一开始找规律找错了.判断超麻烦还各种WA.浪费N个小时啊..人家几行就A了.太弱, #include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype

UVa 10407 - Simple division

题目:给你几个数,求使他们同于的最大除数. 分析:数论.取其中两不相同数的差,差值一定是除数的倍数,利用差值枚举除数即可. 说明:小心都是素数的情况,被坑了╮(╯▽╰)╭. #include <algorithm> #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; long long save[1001];

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

散列表(hash table)&mdash;&mdash;算法导论(13)

1. 引言     许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表     在介绍散列表之前,我们前介绍直接寻址表.     当关键字的全域U(关键字的范围)比较小时,直接寻址是一种简单而有效的技术.我们假设某应用要用到一个动态集合,其中每个元素的关键字都是取自于全域U={0,1,-,m-1},其中m不是一个很大的数.另外,假设每个元素的关键字都不同.    为表示动

Bloom Filter布隆过滤器

http://blog.csdn.net/pipisorry/article/details/64127666 Bloom Filter简介 Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合.布隆过滤器(英语:Bloom Filter)是1970年由布隆提出的.它实际上是一个很长的二进制向量和一系列随机映射函数.布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定