Topic
The number of M points on the axis a1, A2 、... am, and another sequence P1, p2 、... pn, (1≤pii≤m).
Given D1, D2 、... dn, for all I (1≤i≤n), known |api+1-api| = Di, the minimum possible value of M is obtained. (1≤n≤25, 1≤ai≤105)
Original title Link: Http://codeforces.com/group/gRkn7bDfsN/contest/212299/problem/B
Ideas
Basic idea: Enumerate api+1 on the left or right side of the API to reduce complexity, forcing the first selection to the right (or left).
Idea One: Use binary + bitwise operations to enumerate all possible
1#include <stdio.h>2#include <iostream>3#include <algorithm>4#include <cstring>5 using namespacestd;6 7 Const intSIZE = ( -*100000) *2+ -;//the range of the axis8 Const intMAXN = -+Ten;9 intN, D[MAXN];Ten intAns,cnt,vis[size]; One A voidSolve () - { - //enumerate the remaining m-1 options the for(inti =0; I < (1<< (N-1)); i++) - { - intV_num =2; -cnt++; + ints = SIZE/2+ d[0]; - //for (int i = 0; i < SIZE; i++) vis[i] = 0;//this type of marking can cause T +Vis[size/2] =CNT; AVis[size/2+ d[0]] = CNT;//forced to leave the first time to the left at - for(intj =0; J < N-1; J + +) - { - if(I & (1<<j)) -s + = D[j +1]; - Else inS-= D[j +1]; - if(Vis[s]! =CNT) to { +v_num++; -Vis[s] =CNT; the } * } $Ans =min (ans, v_num);Panax Notoginseng } - } the + intMain () A { thescanf"%d", &n); + for(inti =0; I < n; i++) -scanf"%d", &d[i]); $Ans = n +1;//ans will not exceed n+1 $CNT =0; - solve (); -printf"%d\n", ans); the return 0; -}
idea two: Dfs tries every situation
1#include <stdio.h>2#include <iostream>3#include <algorithm>4#include <cstring>5 using namespacestd;6 7 Const intSIZE = -*100000*2+Ten;//the range of the axis, SIZE/2 equivalent to the original point8 Const intMAXN = -+Ten;9 intm, D[MAXN];Ten intVis[size]; One intans; A - //cur+1 State, x position, vertex number v - voidDfsintCurintXintv) the { - if(cur = =m) - { -Ans =min (ans, v); + return; - } + intNET = x +D[cur]; Avis[net]++;//you can't just use 0/1 to differentiate atDFS (cur +1, net, V + (vis[net] = =1)); -vis[net]--; - -NET = x-D[cur]; -vis[net]++; -DFS (cur +1, net, V + (vis[net] = =1)); invis[net]--; - } to + intMain () - { the while(SCANF ("%d", &m) = =1&&m) * { $memset (Vis,0,sizeof(Vis));Panax Notoginseng for(inti =0; I < m; i++) -scanf"%d", &d[i]); theAns = m +1;//ans will not exceed m+1 +Vis[size/2] =1; AVis[size/2+ d[0]] =1;//to impose a first-coming theDfs1, SIZE/2+ d[0],2); +printf"%d\n", ans); - } $ return 0; $}
Dreamoon and MRT (two-dollar enumeration)