首先$C_i$是没有意义的,因为可以直接让$d_i \times= C_i$,答案也是一样的
所以我们现在考虑求$(\sum_{i=1}^{K-1} |d_{p,i}-d_{q,i}|) - |d_{p,K} - d_{q,K}|$的最大值
这个绝对值好烦人啊qaq
我们考虑如何消去这个绝对值
先抛开第$K$项,假设我们要计算$\sum_{i=1}^{K-1} |d_{p,i}-d_{q,i}|$的最大值
可以发现$\sum_{i=1}^{K-1} |d_{p,i}-d_{q,i}| = max(\sum_{i=1}^{K-1} (d_{p,i}-d_{q,i}) \times (-1)^{a_i})=max(\sum_{i=1}^{K-1} d_{p,i} \times (-1)^{a_i} + d_{q,i} \times (-1)^{a_i + 1})$
其中$0 \leq a_i \leq 1$且取遍所有情况
那么我们可以设$dp_j$表示$a_i$状压成二进制表示为$j$时的$\sum_{i=1}^{K-1} d_{p,i} \times (-1)^{a_i}$的最大值,$ind_j$表示$dp_j$取到最大值时的$p$值,转移也比较方便了。
最后我们考虑第$K$维的影响,我们不妨按照第$K$维从小到大排序,那么$dp_j$表示$a_i$状压成二进制表示为$j$时的$\sum_{i=1}^{K-1} d_{p,i} \times (-1)^{a_i} + d_{K,i}$的最大值,最后统计答案时再减去当前的$d_K$值就可以了
#include<bits/stdc++.h> //This code is written by Itst using namespace std; inline int read(){ ; char c = getchar(); ; while(!isdigit(c)){ if(c == '-') f = ; c = getchar(); } while(isdigit(c)){ a = (a << ) + (a << ) + (c ^ '); c = getchar(); } return f ? -a : a; } ; ] , dir[] , C[]; int N , K , ans , ind1 , ind2; struct ani{ ] , ind; bool operator <(const ani a)const{ ] < a.val[K - ]; } }now[MAXN]; inline int calc(int d , int type){ ; ; i < K - ; ++i) sum += (type & ( << i) ? : -) * now[d].val[i]; return sum; } int main(){ #ifndef ONLINE_JUDGE freopen("in" , "r" , stdin); //freopen("out" , "w" , stdout); #endif N = read(); K = read(); ; i < K ; ++i) C[i] = read(); ; i <= N ; ++i){ ; j < K ; ++j) now[i].val[j] = read() * C[j]; now[i].ind = i; } sort(now + , now + N + ); ; i < << (K - ) ; ++i){ dir[i] = now[].ind; dp[i] = calc( , i) + now[].val[K - ]; } ; i <= N ; ++i){ ; j < << (K - ) ; ++j){ << (K - )) - - j; ] > ans){ ans = t + dp[d] - now[i].val[K - ]; ind1 = now[i].ind; ind2 = dir[d]; } } ; j < << (K - ) ; ++j) ]){ dp[j] = calc(i , j) + now[i].val[K - ]; dir[j] = now[i].ind; } } cout << ind1 << ' ' << ind2 << endl << ans; ; }