题意
有 n 个机器人,每个机器人会读入一个 x ,并返回 ax+b 。
现在银临姐姐手里有一个数 x ,她想将机器人按某种顺序排列,使得最终返回得到的 x 尽可能大。
对于所有的数据,1 ≤ n , x , a i , b i ≤ 20 \le n,x,a_i,b_i\le20 ≤n,x,ai,bi≤20 。
分析
状压dp裸题:
f
[
i
]
f[i]
f[i]表示状态为
i
i
i(i中第j位为0表示还没用过第j个机器人,为1时表示已经用过了第j个机器人,j=[0~n-1])时,结果的最大值。
状态更新举例:
f
[
(
111
)
2
]
f[(111)_2]
f[(111)2]要从
f
[
(
011
)
2
]
,
f
[
(
101
)
2
]
,
f
[
(
110
)
2
]
f[(011)_2],f[(101)_2],f[(110)_2]
f[(011)2],f[(101)2],f[(110)2]三个状态更新过来。
f
[
(
111
)
2
]
=
m
a
x
(
a
[
2
]
∗
f
[
(
011
)
2
]
+
b
[
2
]
,
a
[
1
]
∗
f
[
(
101
)
2
]
+
b
[
1
]
,
a
[
0
]
∗
f
[
(
110
)
2
]
+
b
[
0
]
)
f[(111)_2]=max(a[2]*f[(011)_2]+b[2],a[1]*f[(101)_2]+b[1],a[0]*f[(110)_2]+b[0])
f[(111)2]=max(a[2]∗f[(011)2]+b[2],a[1]∗f[(101)2]+b[1],a[0]∗f[(110)2]+b[0])
最终答案就是
f
[
(
1111...11
)
2
]
f[(1111...11)_2]
f[(1111...11)2](n个1)
但是动手算算上界会超longlong。
调了好久的高精都有问题(板子是很久之前写的,现在看起来当时写的并不好),最后__int128水过去了。
关于__int128
仔细整理一下__int128,还挺好用的,我电脑上可以正常使用,不存在网上说的Linux才能用。
但是:
1.__int128的上界是3.4e38,太大了还是不行。
2.要手动实现输入输出函数。
3.位运算的时候要注意写法(被坑过)。
代码
#include <bits/stdc++.h>
using namespace std;
//-----pre_def----
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define fir(i, a, b) for (int i = (a); i <= (b); i++)
#define rif(i, a, b) for (int i = (a); i >= (b); i--)
#define endl '\n'
#define init_h memset(h, -1, sizeof h), idx = 0;
#define lowbit(x) x &(-x)
//---------------
const int N = 23;
int n, x;
int a[N], b[N];
__int128 f[1 << 21];
inline void print(__int128 x)
{
if (x < 0)
{
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
int StartTime = clock();
#endif
scanf("%d%d", &n, &x);
f[0] = x;
fir(i, 0, n - 1)
{
scanf("%d%d", &a[i], &b[i]);
}
for (int i = 1; i <= (1 << n) - 1; i++)
{
for (int j = 0; j < n; j++)
{
if ((i >> j) & 1)
{
f[i] = max(f[i], f[i - (1 << j)] * a[j] + b[j]);
}
}
}
print(f[(1 << n) - 1]);
#ifndef ONLINE_JUDGE
printf("Run_Time = %d ms\n", clock() - StartTime);
#endif
return 0;
}