zoj 2915 hdu 2397 Dice Password Security 动态规划

来源:互联网 发布:杭州淘宝大学地址 编辑:程序博客网 时间:2024/05/01 21:27

zoj 2915 hdu 2397 Dice Password Security 动态规划

原题传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2915

                    http://acm.hdu.edu.cn/showproblem.php?pid=2379

 

这个题,应该是个简单题,但是我很是不明白,想了好久都没想明白,可能是我最近的大脑有点上锈,好吧,看题!

给定一些单词,求有这些单词组成的长度为l的由n个单词组成的字符串有多少个?

动态规划!

但是状态如何找呢??知道看了解题报告才明白,长度相同的单词的个数可以看成是这个长度的价值,即由费用为长度的n多物品放到L的容器中,求价值之积(背包是求和)!!哎,这样想一想,还是被原本我觉得自己学的不错的背包问题给虐了!

贴代码!你懂得


#include <iostream>#include <stdio.h>#include <string.h>using namespace std;int len[60];long long dp[7][60];int main(){    int cas;    cin >> cas;    for(int t = 1;t <= cas;t++)    {        int m,n,q;        cin >> m >> n >> q;        memset(len,0,sizeof(len));        memset(dp,0,sizeof(dp));        for(int i = 0;i < m;i++)        {            string s;            cin >> s;            len[s.length()]++;        }        for(int i = 0;i < 11;i++)        {            dp[1][i] = len[i];            dp[i][i] = len[1];        }        for(int i =1;i < 6;i++)            for(int k = 0;k < 11;k++)                for(int j = 0;j <= 51-k;j++)                    dp[i+1][j+k] += dp[i][j] * len[k];        int l;        while (q--)        {            //scanf("%d",&l);            cin >> l;            //printf("%I64d\n",dp[n][l]);            cout << dp[n][l] << "\n";        }    }    return 0;}