0
点赞
收藏
分享

微信扫一扫

Lightoj 1122 - Digit Count 【DP】

芥子书屋 2023-03-03 阅读 60


题目链接:​​http://www.lightoj.com/volume_showproblem.php?problem=1122​​

题意:给你m个数,选取n个数组成一个整数,使得整数各位的最大数与最小数的差小于2。问有几种选法?

解法:DP。dp[i][j]表示以j结尾的i位整数的解法数目。
答案即为sum(dp[n][k] (1<=k<=9,且k在集合S中) )

代码:

#include <stdio.h>
#include <ctime>
#include <math.h>
#include <limits.h>
#include <complex>
#include <string>
#include <functional>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <bitset>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>

using namespace std;

int n, m;
int p[15];
int dp[15][15];

int main()
{
int t;
int cases = 1;
scanf("%d",&t);
while (t--)
{
memset(dp, 0, sizeof(dp));
memset(p, 0, sizeof(p));

scanf("%d%d", &m, &n);
int x;
for (int i = 1;i <= m;i++)
{
scanf("%d", &x);
p[x] = 1;
}

for (int i = 1;i <= 9;i++)
{
if (p[i])
dp[1][i] = 1;
}

for (int i = 2;i <= n;i++)
for (int j = 1;j <= 9;j++)
{
if (p[j]) dp[i][j] = 0;

for (int k = 1;k <= 9;k++)
{
if (abs(k - j) <= 2 && p[k])
dp[i][j] += dp[i-1][k];
}
}

int ans = 0;
for (int i = 1;i <= 9;i++)
if (p[i]) ans += dp[n][i];

printf("Case %d: %d\n", cases++, ans);
}
return 0;
}


举报

相关推荐

0 条评论