zoj 2915 hdu 2397 Dice Password Security 动态规划

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;
}


 

你可能感兴趣的:(zoj 2915 hdu 2397 Dice Password Security 动态规划)