题目大意:
给你n个数,求出一个子集,使得子集的乘积%10为一个值,并且使得子集的乘积最大
n <= 1e5 ai <= 1000
直接dp的答案不能存下来,就取对数然后判断
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int maxn = 1e5 + 10;
int n, d, a[maxn];
double f[maxn][15];
PII pre[maxn][15];//用来记录dp转移过程的数组。
int num[maxn][15];
int idx, ans[maxn];
int main() {
cin >> n >> d;
for(int i = 0; i <= 9; ++ i) f[0][i] = -1e9, pre[0][i] = {-1,-1};
for(int i = 1; i <= n; ++ i) {
cin >> a[i];
double x = log2(a[i]);
for(int j = 0; j <= 9; ++ j) f[i][j] = f[i - 1][j], pre[i][j] = pre[i - 1][j], num[i][j] = num[i - 1][j];
for(int j = 0; j <= 9; ++ j) {
int k = j * a[i] % 10;
if(k == a[i] % 10) {
if(f[i][k] < (double)x)
pre[i][k] = {-1,i}, f[i][k] = x, num[i][k] = k;
}
if(f[i - 1][j] == -1e9) continue;
if(f[i - 1][j] + x > f[i][k]) {
f[i][k] = f[i - 1][j] + x;
pre[i][k] = {pre[i - 1][j].second,i};
num[i][k] = j;
}
}
}
if(f[n][d] == -1e9) {
cout << "-1";
return 0;
}
// for(int i = 1; i <= n; ++ i)
// for(int j = 0; j <= 9; ++ j)
// cout << "{" << pre[i][j].first << "," << pre[i][j].second << "}" << " \n"[j == 9];
// cout << endl;
// for(int i = 1; i <= n; ++ i)
// for(int j = 0; j <= 9; ++ j)
// cout << num[i][j] << " \n"[j == 9];
while(pre[n][d].first != -1) {
ans[idx ++] = a[pre[n][d].second];
// cout << pre[n][d].second <<endl;
int t = d;
d = num[n][d];
n = pre[n][t].first;
}
ans[idx++] = a[pre[n][d].second];
cout << idx << endl;
for(int i = 0; i < idx; ++ i)
cout << ans[i] << " ";
return 0;
}
/*
for(int i = 1; i <= n; ++ i) {
cin >> a[i];
//double x = log(a[i]);
int x = a[i];
for(int j = 0; j <= 9; ++ j) f[i][j] = f[i - 1][j];
for(int j = 0; j <= 9; ++ j) {
int k = j * a[i] % 10;
if(k == a[i] % 10)
f[i][k] = max(f[i][k],(double)a[i]);
if(f[i - 1][j] * x > f[i][k]) {
f[i][k] = f[i - 1][j] * x;
}
}
}
*/
打不过就加入!