题目链接:https://codeforces.com/contest/1673/problem/C
样例输入:
2
5
12
样例输出:
7
74
翻译(参考):
有t组数据,每一组给出一个正整数n,对每个n输出它可以有多少种由没有前导零的回文整数相加得到的方案。
题解:
转化成完全背包问题,对每种可能的组合,其中的整数必须是没有前导零的回文整数,这些整数看作成物品的重量,对每个整数n看做成背包的最大容量。
接下来只需要存下没有前导零的回文整数,然后就是经典的完全背包问题了,因为空间限制,完全背包需要转化为一维。再就是预处理1~4000的f[n],因为样例最多可以有10000组,每次跑一遍完全背包肯定超时的。
详见代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
ll a[40009], cnt, f[40009];
bool jud(int x) //判断是否是回文整数
{
int k = 0;
int a[10] = {0};
while (x) //将x的每一位存入数组a中
{
a[++k] = x % 10;
x /= 10;
}
for (int i = 1; i <= k; i++) //循环判断是否是回文数
if (a[i] != a[k - i + 1])
return false;
return true;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); //关同步流
int T;
cin >> T;
for (int i = 1; i <= 40000; i++)
if (jud(i))
a[++cnt] = i; //存下回文数
f[0] = 1;
for (int i = 1; i <= cnt; i++) //完全背包
{
for (int c = 0; c <= 40000; c++)
{
if (c >= a[i])
f[c] = (f[c] % mod + f[c - a[i]] % mod) % mod;
}
}
while (T--)
{
int n;
cin >> n;
cout << f[n] % mod << "\n"; //输出方案数
}
}