让原子核放出的能量最少. 现在给
t
(
t
≤
1
0
5
)
t(t \le 10^5)
t(t≤105) 个测试, 每次询问的原子核的大小是
k
(
k
≤
1
0
9
)
k(k \le 10^9)
k(k≤109).
这个题和之前小米那个不一样。小米的是01背包。
一开始优先选择性价比最优的,到达一定范围的时候,就开始跑暴力。因此暴力可以预处理,至于暴力的范围,可以猜一猜,至少这个题预处理出
n
2
n^2
n2 即可.
这样做的原理是,前面跑暴力之后,后面会形成一个等差序列,然后找到最优的起点即可.
#include<bits/stdc++.h>usingnamespace std;constint N =21000;typedeflonglong ll;
ll f[N], a[N];int n, q;intmain(){scanf("%d%d",&n,&q);for(int i =1; i <= n; i++)scanf("%lld",&a[i]);for(int i = n +1; i <= n * n; i++) f[i]=1e18;for(int i =1; i <= n; i++) f[i]= a[i];for(int i = n +1; i <= n * n; i++){for(int j =1; j < i; j++){
f[i]=min(f[i], f[j]+ f[i - j]);}}
ll mina = a[1], minv =1;for(ll i =1; i <= n; i++){if(mina * i > minv * a[i]){
mina = a[i];
minv = i;}}while(q--){
ll k;scanf("%lld",&k);if(k <= n * n){printf("%lld\n", f[k]);}else{
ll cnt =(k - n * n)/ minv -1;while(k - cnt * minv > n * n) cnt++;printf("%lld\n", cnt * mina + f[k - cnt * minv]);}}return0;}
I. Island Tour
题意:有一个环形道路有 n 个点(
n
≤
400
n \le 400
n≤400),给出从第
i
i
i 个点到第
i
+
1
i+1
i+1 个点的观光时间. 然后给出这三个人在每个观光点需要花费多少时间。现在让找到三个点作为这三个人的起始观光点,保证这三个人不会碰面(一个人从一个观光点的离开的同时另一个人到这个观光点不算碰面),一个人旅游完最后一个观光点后会立刻离开。
一个很简单的思路是,分开预处理,每次处理两个人,
O
(
n
2
)
O(n^2)
O(n2) 枚举他们分别的起点,然后
O
(
n
)
O(n)
O(n) 的时间判断他们是否会相遇。然后再枚举三个人的起点(看看
d
i
s
a
b
(
i
,
j
)
,
d
i
s
a
c
(
i
,
k
)
,
d
i
s
b
c
(
j
,
k
)
disab(i,j),disac(i, k), disbc(j, k)
disab(i,j),disac(i,k),disbc(j,k) 是否都满足).