Original question Portal: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4016
This question is obviously search, but it requires a lot of pruning! Very high! Because the maximum value of N is 40, that is, profiteering search cannot be done, because I know that profiteering search can be searched for more than a dozen.
When I know that this competition and the next competition are all questions, I think it is better to understand each question.
The pruning of this question is not my idea. The idea comes from the network. In the end, I used this idea to rank the code first! I'm glad that it's not my idea.
The idea of the original article is as follows:
1. Starting from the current value, if you select all the remaining values and cannot be less than the obtained optimal values, return.
2. The optimal value does not need to be updated until the number of K is accumulated. Instead, it is updated constantly because it is smaller than the calculation result, so this is also a pruning.
3. Pre-processing, sorting from small to large. We can imagine that we should select a small one first, and the obtained optimal value is closer to the result. It is a strong pruning, without this 2900 MS +, plus 600 MS +.
As a matter of fact, the main theory of optimization above is that the smaller and smaller it is, the more clear it is!
Note the following:
A: There is a for loop in recursion in the original code. This is a big taboo! The simpler the code in recursion, the better! After this is changed, the code is optimized to 187 Ms!
B: There is a search order in the Code, namely, DFS (t + 1, D + 1, M & A [T]); and DFS (t + 1, D, m );. The order of the two cannot be changed! This is also a small pruning! Of course, this is the pruning technique I just understood in the search! The reason is that the first search is short. When the search is long, you can cut a considerable number of long branches. However, if you search for longer branches first, the effect will not be obvious during the short cut! In other words, we need to make the minimum known value smaller as soon as possible. In fact, the original code is time-out after switching, and the optimized code also has 2750 Ms.
C: The above two ideas seem useless, but when I want to understand B, I think 2 is so wonderful !!
Original article: http://hi.baidu.com/jiantaodongshe/blog/item/2b489b1c3d61bc04403417f7.html
My code:
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N=45;__int64 MAX=0x7fffffffffffffff;int t,c,n,k;__int64 a[N],ans;__int64 sum[N];void dfs(int t,int d,__int64 num){ if(ans>num)ans=num; if(d==k||t==n+1) return; __int64 s=num; s &= sum[t]; if(s>=ans)return; dfs(t+1,d+1,num&a[t]); dfs(t+1,d,num); }int main(){ cin>>t; c=0; while(t--) { printf("Case #%d: ",++c); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%I64d",&a[i]); sort(a+1,a+n+1); sum[n] = a[n]; for(int i = n-1;i >= 1;i--) sum[i] = a[i] & sum[i+1]; ans=MAX; dfs(1,0,MAX); printf("%I64d\n",ans); } return 0;}