题目链接: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;
}
版权声明:转载请注明出处。
时间: 2024-10-16 07:16:56