[WC2005]友好的生物
这题算是毒瘤吧,看到这个题我除了O(n^2)想不到别的方法
后来尝试使用平方的方式乱搞,但是给出了反例
在看了国家集训队ysy的解题报告后方才明白
思路是一种放宽的思路
我们枚举每个差值的符号,在其中枚举最大值,就可以有效去除绝对值
最后按照第k位从小到大排序,来枚举
从小到大进行扫描,每次用当前的值减去他前缀的最小值即可
但是在我看了部分题解后,我发现大家没有写什么要排序
而我就正好卡在这了,我太弱了
按照第k位从小到大排序,是为了后面的数第k种属性大于前面的
这样减出来第k个属性的差值一定是负值,满足条件
实现如下:
#include <algorithm> #include <iostream> #include <cmath> #include <cstring> #include <map> #include <string> #include <vector> #include <queue> #include <stack> #include <cstdio> #include <cstdlib> using namespace std; typedef long long ll; inline ll read() { register ll p(1),a(0);register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if(ch=='-') p=-1,ch=getchar(); while(ch>='0'&&ch<='9') a=a*10+ch-48,ch=getchar(); return a*p; } const int N=100100; int n,k,c[10],minn,num,ans,minid,t1,t2; struct node { int a[10],xu; bool operator < (const node &xx)const { return a[k]<xx.a[k]; } }po[N]; int main() { // freopen("input","r",stdin); // freopen("output","w",stdout); n=read(),k=read(); for(int i=1;i<=k;i++) c[i]=read(); for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) po[i].a[j]=read()*c[j],po[i].xu=i; sort(po+1,po+1+n); for(int i=(1<<(k-1))-1;i>=0;i--) { minn=0x3f3f3f3f; for(int j=1;j<=n;j++) { num=0; for(int l=k-1;l>=1;l--) num+=(i&(1<<(l-1)))?-po[j].a[l]:po[j].a[l]; num-=po[j].a[k]; ans=max(ans,num-minn); if(ans==num-minn) t1=minid,t2=po[j].xu; minn=min(minn,num);if(minn==num) minid=po[j].xu; } } printf("%d %d\n%d",t1,t2,ans); return 0; } /* */