forked from ISTE-VIT/CodeZap-2020
-
Notifications
You must be signed in to change notification settings - Fork 0
/
three-wheel-trouble.cpp
129 lines (117 loc) · 3.16 KB
/
three-wheel-trouble.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template<typename T>
using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
const int infI=1e9+5;
const long long infL=1e16;
const int MOD=1e9+7;
const int MAX=2e5+5;
#define mp make_pair
#define in &
#define pb push_back
#define ii pair<int,int>
#define iii pair<ii,int>
#define ll long long
#define pll pair<ll,ll>
#define vvl vector<vector<ll> >
#define vi vector<int>
#define vvi vector<vector<int> >
#define vl vector<ll>
#define eb emplace_back
#define forn(i,a,b) for(ll i=a;i<b;i++)
#define fastio ios_base::sync_with_stdio(0);cin.tie(0)
#define endl '\n'
#define popb pop_back()
#define se second
#define fi first
#define test(t) int t;cin>>t;while(t--)
#define debug(x) cerr<<"=>"<<#x<<" = "<<x<<endl
ll power(ll a,ll b){
if(b==0){
return 1;
}
if(b==1){
return a;
}
ll temp=power(a,b/2);
temp=(temp*temp)%MOD;
if(b%2){
temp=(temp*a)%MOD;
}
return temp;
}
//only use if mod is prime
ll mod_inv(ll a,ll mod){
a%=mod;
return power(a,mod-2);
}
void extended_gcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1;
y=0;
return;
}
ll x1,y1;
extended_gcd(b,a%b,x1,y1);
x=y1;
y=x1-((a/b)*y1);
return;
}
//TLE can also occur if vectors are not passed by reference
//priority_queue implements max heap by default
ll dp[1005][1005],a[1005];//dp[i][j] -> minimum number of hits to break j coconuts from first i,i+1,i+2.....n and last used coconut was the i'th one
ll get_cost(pll a,ll b){
return (a.fi-a.se*b);
}
bool slope(pll a,pll b,pll c){
ll val1 = (b.fi - a.fi)*(c.se - b.se);
ll val2 = (c.fi - b.fi)*(b.se - a.se);
return val1>=val2;
}
int main(){
int zz;
scanf("%d",&zz);
while(zz--){
int n,z;
scanf("%d %d",&n,&z);
forn(i,1,n+1){
scanf("%lld",&a[i]);
forn(j,1,z+1){
dp[i][j] = infL;
}
}
sort(a+1,a+n+1,greater<ll>());
forn(i,1,n+1){
dp[i][1] = a[i]*i;
}
forn(j,2,z+1){
pll dq[n+1];
int fptr = 1,bptr = 2;
dq[1] = mp(dp[j-1][j-1],j-1);
forn(i,j,n+1){
pll part = mp(dp[i][j-1],i);
while(bptr-fptr>=2 and get_cost(dq[bptr-1],a[i])>=get_cost(dq[bptr-2],a[i])){
--bptr;
}
dp[i][j] = get_cost(dq[bptr-1],a[i]) + i*a[i];
// while(bptr-fptr>=1 and dp[dq[bptr-1].se][j-1] >= dp[i][j-1]){
// --bptr;
// }
while(bptr-fptr>=2 and slope(dq[bptr-2],dq[bptr-1],part)){
--bptr;
}
dq[bptr++] = part;
}
}
ll ans = infL;
forn(i,1,n+1){
// cerr<<dp[i][z]<<" ";
ans = min(ans,dp[i][z]);
}
printf("%lld\n",ans);
}
return 0;
}