多校联合训练2016---hdu5798Stabliztion
2016-08-13 09:47
459 查看
一个压缩状态 + 记忆搜索/DFS非顺序枚举 的题目。。
TLE的同学记得一定要用G++提交。否者如果是C ++ ,标程都TLE。表示时间限制很紧,标程都是1800ms,我的是2800ms......
首先很容易想到的思路是,,X的每一位如果是1.都会对10^5个数产生影响。。记录变化下来,然后枚举X,再循环x的每一位,如果是1,就加上这个变化。。
但是也就自然的把10^5-1个差压缩成了d[20],也就是i位变化,所有的数的变化和。。。
但是考虑到,如果两个相邻的数。他们的最高的不同位发生了变化,那么两个的相对大小会发生变化。。那么之前求的j位(j < i)变化,要取反。。。
这样就加加入了一维。。d[i][j]表示最高不同位是i的所有数。。j位发生变化产生的总的影响是多少。。其实也就相当于是求贡献。。每一个数的贡献和就是结果,但是每一个数都有些许不同(最高不同位)这样就要分开来。所以引入了那个数组。这个思想是很重要的,也是找出状态的关键。。
有了d数组,这样的话。朴素枚举每一个x,每一个x中在对d的两维枚举,满足条件就+d[i][j],但是注意取反的情况,这样也就很简单了。
可是20*20*2^20会超时。。。
考虑优化:找出不同的x中,有没有共同点。。因为
0000100010101
1010100010101
对于上面两个数据,考虑第一个数第一个1时,如果算出来了,那么对于下面的第3个1,因为后面完全相同,虽然前面不同,但是因为最高位是在后面。,这些不同的位不产生影响。所以,还是相等的。。。
这样考虑记录数组t[20][2^20]。。。记录数据。,。
然后发现会超空间。。。
但是用贡献的思路考虑。先枚举x,在枚举i,和先枚举i然后在枚举x,对于每一个x贡献是一样的。。
所以可以改变枚举顺序。。。。(很重要的思路) ;
就可以把t数组变为t[2^20] ; 很叼的题目。。很好。。。
TLE的同学记得一定要用G++提交。否者如果是C ++ ,标程都TLE。表示时间限制很紧,标程都是1800ms,我的是2800ms......
首先很容易想到的思路是,,X的每一位如果是1.都会对10^5个数产生影响。。记录变化下来,然后枚举X,再循环x的每一位,如果是1,就加上这个变化。。
但是也就自然的把10^5-1个差压缩成了d[20],也就是i位变化,所有的数的变化和。。。
但是考虑到,如果两个相邻的数。他们的最高的不同位发生了变化,那么两个的相对大小会发生变化。。那么之前求的j位(j < i)变化,要取反。。。
这样就加加入了一维。。d[i][j]表示最高不同位是i的所有数。。j位发生变化产生的总的影响是多少。。其实也就相当于是求贡献。。每一个数的贡献和就是结果,但是每一个数都有些许不同(最高不同位)这样就要分开来。所以引入了那个数组。这个思想是很重要的,也是找出状态的关键。。
有了d数组,这样的话。朴素枚举每一个x,每一个x中在对d的两维枚举,满足条件就+d[i][j],但是注意取反的情况,这样也就很简单了。
可是20*20*2^20会超时。。。
考虑优化:找出不同的x中,有没有共同点。。因为
0000100010101
1010100010101
对于上面两个数据,考虑第一个数第一个1时,如果算出来了,那么对于下面的第3个1,因为后面完全相同,虽然前面不同,但是因为最高位是在后面。,这些不同的位不产生影响。所以,还是相等的。。。
这样考虑记录数组t[20][2^20]。。。记录数据。,。
然后发现会超空间。。。
但是用贡献的思路考虑。先枚举x,在枚举i,和先枚举i然后在枚举x,对于每一个x贡献是一样的。。
所以可以改变枚举顺序。。。。(很重要的思路) ;
就可以把t数组变为t[2^20] ; 很叼的题目。。很好。。。
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <string> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <sstream> #include <cstdlib> #include <iostream> #include <algorithm> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; #define MAX 1000005 #define MAXN 2000005 #define maxnode 500010 #define sigma_size 30 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lrt rt<<1 #define rrt rt<<1|1 #define mid int m=(r+l)>>1 #define LL long long #define ull unsigned long long #define mem0(x) memset(x,0,sizeof(x)) #define mem1(x) memset(x,-1,sizeof(x)) #define meminf(x) memset(x,INF,sizeof(x)) #define lowbit(x) (x&-x) #define S(n) scanf("%d",&n) #define P(n) printf("%d ",n) #define PN(n) printf("%d\n",n) #define FP(k) freopen(k , "r" ,stdin) #define RPTI(s , n) for(int i=s;i<n;i++) #define RPTJ(s , n) for(int j=s;j<n;j++) #define RPTK(s , n) for(int k=s;k<n;k++) #define RPTL(s , n) for(int l=s;l<n;l++) const LL mod = 1000000; ///const int prime = 999983; const int INF = 0x3f3f3f3f; const int INFF = 1e9; const double pi = 3.141592653589793; const double inf = 1e18; const double eps = 1e-10; inline int read_int(){ int ret=0; char tmp; while(!isdigit(tmp=getchar())); do{ ret=(ret<<3)+(ret<<1)+tmp-'0'; } while(isdigit(tmp=getchar())); return ret; } /*******************************************/ typedef long long ll ; const int moddd = 1e9+7 ; int a[100005] ; const int maxn = (1 << 20) ; ll d[20][20] ; ll t[maxn] ; ll ji[maxn] ; int bin[25] ; const int wei = 20 ; int main(){ int jie = 1 ; for(int i=0;i<20;i++ , jie*=2){ bin[i] = jie ; } int n , m ; ///freopen("in.txt" , "r", stdin) ; int T ;scanf("%d" , &T) ; while(T --){ for(int j=0;j<maxn;j++) ji[j] = inf ; mem0(t) ; mem0(d) ; scanf("%d" , &n) ; for(int i=0;i<n;i++) scanf("%d" , &a[i]) ; ll tot = 0 ; int maxx = 0 ; for(int i=0;i<20;i++){ for(int j=0;j<n;j++){ if(a[j] & bin[i]) { maxx = i ; } } } for(int i=0;i<n-1;i++) { int t1 = a[i] ; int t2 = a[i+1] ; if(t1 > t2) swap(t1 , t2) ; tot += (t2 - t1) ; int tmp = t2 - t1 ; int ti = 0 ; for(int j=wei-1;j>=0;j--){ bool b1 = t2 & bin[j] ; bool b2 = t1 & bin[j] ; if(b1 != b2) { ti = j ;break ; } } for(int j=0;j<wei;j++){ d[ti][j] += abs((t2^bin[j])-(t1^bin[j])) - tmp ; } } ll ans = tot ; ll mii = 0 ; ll counter = 0 ; int upper = (1 << (maxx)) ; for(int i=0;i<upper;i++) t[i] = tot ; for(int i=0;i<wei;i++){ for(int x=0;x<upper;x++) ji[x] = inf ; for(int x=0;x<upper;x++){ ll tmp = 0 ; int tx = x % (bin[i] << 1) ; if(ji[tx] != inf) { t[x] += ji[tx] ; continue ; } else{ int flag = 0 ; if(x & bin[i]) flag = 1 , tmp += d[i][i] ; for(int j=0;j<wei;j++){ ///counter ++ ; if(x & bin[j]){ if(flag == 0) tmp += d[i][j] ; else if(j < i) tmp -= d[i][j] ; } } ji[tx] = tmp ; t[x] += tmp ; } } } for(int i=0;i<upper;i++){ if(t[i] < ans) { ans = t[i] ; mii = i ; } } //cout << "counter = " << maxn <<" "<< counter << endl ; cout << mii << " " << ans << endl ; } }
相关文章推荐
- HDOJ 5752 (2016多校联合训练 Training Contest 3) Sqrt Bo
- [HDU5799] This world need more Zhu [2016 Multi-University Training Contest 6(2016多校联合训练2) 1007]
- 2016多校联合训练7&&HDU5818
- 2016多校联合训练5&&HDU5784 How Many Triangles
- [HDU5788] Level Up [2016 Multi-University Training Contest 5 1008 (2016多校联合训练5)]
- HDOJ 5794 (2016多校联合训练 Training Contest 6) A Simple Chess
- HDOJ 5738 (2016多校联合训练 Training Contest 2) Eureka
- HDOJ 5753 (2016多校联合训练 Training Contest 3) Permutation Bo
- [HDU5756] Boss Bo [2016 Multi-University Training Contest 3(2016多校联合训练3) E]
- [HDU5764] After a Sleepless Night [2016 Multi-University Training Contest 4(2016多校联合训练4) B]
- HDOJ 5763 (2016多校联合训练 Training Contest 4) Another Meaning
- HDOJ 5775 (2016多校联合训练 Training Contest 4) Bubble Sort
- 2016多校联合训练4 F - Substring 后缀数组
- HDOJ 5744 (2016多校联合训练 Training Contest 2) Keep On Movin
- HDOJ 5734 (2016多校联合训练 Training Contest 2) Acperience
- 2016多校联合训练10&&HDU5857 Median
- [HDU5739] Fantasia [2016 Multi-University Training Contest 2(多校联合训练2) F]
- HDOJ 5773 (2016多校联合训练 Training Contest 4) The All-purpose Zero
- HDOJ 5792 (2016多校联合训练 Training Contest 5) World is Exploding
- [HDU5828] Rikka with Sequence [2016 Multi-University Training Contest 8(2016多校联合训练8) 1008]