Codeforces Round #598 (Div. 3)
思路
首先我们可以确定是选择的team长度最长为5,因为如果是6的话我们很可能有更优的选择权,而且当我们倒着弄 i − > i + 2 i − > i + 3 i − > i + 4 i->i+2\quad i->i+3\quad i->i+4 i−>i+2i−>i+3i−>i+4是可以遍历每一种可能的。
在遍历的过程中我们在 m i n n minn minn数组中存了每个团队的上界和下界,比如说 m i n n [ i + 3 ] = i minn[i+3]=i minn[i+3]=i,那么就是 i − > i + 3 i->i+3 i−>i+3
便于我们后期给 a n s ans ans数组赋答案。
转移方程:
d
p
[
i
+
2
]
=
d
p
[
i
−
1
]
+
n
o
d
e
[
i
+
2
]
.
v
−
n
o
d
e
[
i
]
.
v
d
p
[
i
+
3
]
=
d
p
[
i
−
1
]
+
n
o
d
e
[
i
+
3
]
.
v
−
n
o
d
e
[
i
]
.
v
d
p
[
i
+
4
]
=
d
p
[
i
−
1
]
+
n
o
d
e
[
i
+
4
]
.
v
−
n
o
d
e
[
i
]
.
v
dp[i+2]=dp[i-1]+node[i+2].v-node[i].v\\ dp[i+3]=dp[i-1]+node[i+3].v-node[i].v\\dp[i+4]=dp[i-1]+node[i+4].v-node[i].v
dp[i+2]=dp[i−1]+node[i+2].v−node[i].vdp[i+3]=dp[i−1]+node[i+3].v−node[i].vdp[i+4]=dp[i−1]+node[i+4].v−node[i].v
每次可能比上一次优就更新。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(case, x) cout << case << " : " << x << endl
#define open freopen("ii.txt", "r", stdin)
#define close freopen("oo.txt", "w", stdout)
#define IO \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0)
#define pb push_back
using namespace std;
// #define int long long
#define lson rt << 1
#define rson rt << 1 | 1
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> PII;
const int maxn = 2e5 + 10;
int dp[maxn],ans[maxn],minn[maxn];
struct node{
int v,pos;
bool operator<(const node x)const{
return v<x.v;
}
}node[maxn];
void solve() {
int n;cin>>n;
for(int i=1;i<=n;++i){
cin>>node[i].v;
node[i].pos=i;
}
sort(node+1,node+1+n);
for(int i=1;i<=n;++i){
dp[i]=1e9;
}
for(int i=1;i<=n;++i){
if(i+3<=n+1){
if(dp[i+2]>=dp[i-1]+node[i+2].v-node[i].v)
dp[i+2]=dp[i-1]+node[i+2].v-node[i].v,minn[i+2]=i;
}
if(i+4<=n+1){
if(dp[i+3]>=dp[i-1]+node[i+3].v-node[i].v)
dp[i+3]=dp[i-1]+node[i+3].v-node[i].v,minn[i+3]=i;
}
if(i+5<=n+1){
if(dp[i+4]>=dp[i-1]+node[i+4].v-node[i].v)
dp[i+4]=dp[i-1]+node[i+4].v-node[i].v,minn[i+4]=i;
}
}
// for(int i=1;i<=n;++i){
// debug(i,dp[i]);
// }
int tot=0;
int now=n;
while(now!=0){
++tot;
for(int i=now;i>=minn[now];--i)
ans[node[i].pos]=tot;
now=minn[now]-1;
}
cout<<dp[n]<<' '<<tot<<endl;
for(int i=1;i<=n;++i){
cout<<ans[i]<<' ';
}
}
int main() {
// int t;
// cin >> t;
// while(t--) {
solve();
// }
}