Dreamoon and MRT
Dreamoon and MRT
题目链接:
http://codeforces.com/group/gRkn7bDfsN/contest/212299/problem/B
只需要考虑相对位置,设a0位置为0
枚举
由于对称性,可以设第一步向右,这样总时间减少一半
递归的话省去了cnt部分,直接从O(N2^N-1)变成了O(2^N-1)
可以分析一下几个代码的优化过程
#include <bits/stdc++.h> using namespace std; int n, a[30], b[30], c, cnt, ans = 25; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < (1 << n); i++) { int s = 0; c++; cnt = 1; b[0] = s; for (int j = 0; j < n; j++) { if (i >> j & 1) s += a[j]; else s -= a[j]; b[j + 1] = s; } sort(b, b + n + 1); ans = min(ans, (int)(unique(b, b + n + 1) - b)); } printf("%d\n", ans); }
#include <bits/stdc++.h> using namespace std; int n, a[30], b[30], c, cnt, v[5000001], ans = 25; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < (1 << n); i++) { int s = 25 * 100000; c++; cnt = 1; v[s] = c; for (int j = 0; j < n; j++) { if (i >> j & 1) s += a[j]; else s -= a[j]; if (v[s] != c) { cnt++; v[s] = c; } } ans=min(ans,cnt); } printf("%d\n", ans); }
#include <bits/stdc++.h> using namespace std; int n, a[30], b[30], c, cnt, v[5000001], ans = 25; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < (1 << n); i+=2) { int s = 25 * 100000; c++; cnt = 1; v[s] = c; for (int j = 0; j < n; j++) { if (i >> j & 1) s += a[j]; else s -= a[j]; if (v[s] != c) { cnt++; v[s] = c; } } ans=min(ans,cnt); } printf("%d\n", ans); }
#include <bits/stdc++.h> using namespace std; const int SIZE = 5e6+10; int m,cnt[SIZE],an,d[30]; void dfs(int i,int x,int v){ if(i==m){ an=min(an,v); return; } int nxt=x+d[i]; cnt[nxt]++; dfs(i+1,nxt,v+(cnt[nxt]==1)); cnt[nxt]--; nxt=x-d[i]; cnt[nxt]++; dfs(i+1,nxt,v+(cnt[nxt]==1)); cnt[nxt]--; } int main(){ scanf("%d",&m); an=m+1; for(int i=0;i<m;i++) scanf("%d",&d[i]); cnt[SIZE/2]=1;//0 cnt[SIZE/2+d[0]]=1;//强制第一步向右 dfs(1,SIZE/2+d[0],2); printf("%d\n",an); return 0; }