数论?? dp?? 图论??
题目描述
给定n个数 求用这n个数任意相加(每个数可以加0次或多次)所不能表示的数的最大值ans
输入描述 第一行输入一个数n,第二行输入n个数a[1] a[2] a[3] … a[n] 。
输出描述 输出ans,若ans不存在则输出0
样例1
input:
3
7 8 9
output:
20
样例2
input:
2
5 10
output:
0
题解 乍一看像个数论,参考NOIP2017小凯的疑惑。后来有人说这是个完全背包的dp。然而我最佩服的还是神仙姐姐xjb搞的Floyd。
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int n;
long long a[20], f[600][600], ans;
int gcd(int a, int b){return b == 0 ? a : gcd(b, a % b);}
int main(){
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
for (int i = 0; i < a[1]; i++)
for (int j = 0; j < a[1]; j++) f[i][j] = INF;
for (int i = 0; i < a[1]; i++)
for (int j = 1; j <= n; j++){
int x = (i + a[j]) % a[1];
f[i][x] = min(f[i][x], a[j]);
}
for (int k = 0; k < a[1]; k++)
for (int i = 0; i < a[1]; i++)
for (int j = 0; j < a[1]; j++)
f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
for (int i = 0; i < a[1]; i++)
if (f[0][i] == INF){ ans = 0; break;}
else ans = max(ans, f[0][i] - a[1]);
cout << ans << endl;
return 0;
}