官方题解:
考虑去掉abs符号,发现只有相邻两个数的最高位被影响了才会影响abs的符号,所以可以按照最高位不一样的位置分类,之后考虑朴素枚举x从0到2^20,每次的复杂度是O(400),无法通过,考虑优化,第一种方法是用DFS来进行枚举,第二种则是加入记忆化
用dfs枚举简单一点
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 int d[20],n,mx,ansx; 6 ll anss,c[20][20]; 7 void dfs(int i,int x,ll s) 8 { 9 if (s>anss) return; 10 if (i>mx) 11 { 12 if (s<anss||(s==anss&&x<ansx)) 13 { 14 anss=s; 15 ansx=x; 16 } 17 return; 18 } 19 for (d[i]=0; d[i]<=1; d[i]++) 20 { 21 ll ns=s+c[i][i]; 22 for (int j=0; j<i; j++) 23 if (d[i]^d[j]) ns-=c[i][j]; 24 else ns+=c[i][j]; 25 dfs(i+1,x+d[i]*(1<<i),ns); 26 } 27 } 28 29 int work(int a,int b,int h) 30 { 31 if (a<b) swap(a,b); 32 for (int i=h; i>=0; i--) 33 c[h][i]+=((a>>i&1)-(b>>i&1))<<i; 34 } 35 36 int main() 37 { 38 int cas; 39 scanf("%d",&cas); 40 while (cas--) 41 { 42 scanf("%d",&n); 43 int a,b; 44 scanf("%d",&a); 45 memset(c,0,sizeof(c)); 46 mx=19; 47 for (int i=1; i<n; i++) 48 { 49 scanf("%d",&b); 50 int h=19; 51 while (h>=0&&!((a>>h&1)^(b>>h&1))) h--; 52 work(a,b,h); 53 a=b; 54 } 55 while (mx>=0&&!c[mx][mx]) mx--; 56 anss=1e18; ansx=0; 57 dfs(0,0,0); 58 printf("%d %lld\n",ansx,anss); 59 } 60 }
#include<bits/stdc++.h> using namespace std; typedef long long ll; int d[20],n,mx,ansx; ll anss,c[20][20]; void dfs(int i,int x,ll s) { if (s>anss) return; if (i>mx) { if (s<anss||(s==anss&&x<ansx)) { anss=s; ansx=x; } return; } for (d[i]=0; d[i]<=1; d[i]++) { ll ns=s+c[i][i]; for (int j=0; j<i; j++) if (d[i]^d[j]) ns-=c[i][j]; else ns+=c[i][j]; dfs(i+1,x+d[i]*(1<<i),ns); } } int work(int a,int b,int h) { if (a<b) swap(a,b); for (int i=h; i>=0; i--) c[h][i]+=((a>>i&1)-(b>>i&1))<<i; } int main() { int cas; scanf("%d",&cas); while (cas--) { scanf("%d",&n); int a,b; scanf("%d",&a); memset(c,0,sizeof(c)); mx=19; for (int i=1; i<n; i++) { scanf("%d",&b); int h=19; while (h>=0&&!((a>>h&1)^(b>>h&1))) h--; work(a,b,h); a=b; } while (mx>=0&&!c[mx][mx]) mx--; anss=1e18; ansx=0; dfs(0,0,0); printf("%d %lld\n",ansx,anss); } }
时间: 2024-11-06 12:00:50