题目链接:51nod1693 水群
题解参考大神的博客:http://www.cnblogs.com/fighting-to-the-end/p/5874763.html
这题时限0.4秒,真的够狠的。。我用优化过的dij狂交一直TLE,最后还是死在四百多毫秒上,应该是姿势不对orz。后来看别人用spfa,然后一改就过了,这里我想收藏一下记忆化搜索的解法,真心服了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 1000010; 6 const int inf = 0x3f3f3f3f; 7 int n; 8 int pri[] = {2,3,5,7,11}; 9 int s[N][2];//1到i上一条边的状态是f的最小操作数 10 //j=0时,上一条边可以是i->i-1,否则是i->i*p 11 int dfs(int x, int f){ 12 if(x == 1) return 0; 13 if(s[x][f]) return s[x][f]; 14 s[x][f] = inf; 15 for(int i = 0; i < 4; i++) 16 if(!(x % pri[i])) 17 s[x][f] = min(s[x][f], dfs(x /pri[i], 1) + pri[i]); 18 if(!f) return s[x][f]; 19 s[x][0] = s[x][1]; 20 for(int i = 1; i < 3; i++) 21 s[x][f] = min(s[x][f], dfs( x + i, 0) + i); 22 return s[x][f]; 23 } 24 int main(){ 25 scanf("%d", &n); 26 printf("%d ", dfs(n, 1)); 27 return 0; 28 }
再贴上我这份超时了的dij,我写的好差啊,只好说我刚刚入门最短路姿势还不够orz
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #define CLR(a,b) memset((a),(b),sizeof((a))) 7 using namespace std; 8 #define inf 0x3f3f3f3f 9 const int N = 1000010; 10 int d[N], vis[N]; 11 int prime[] = {2, 3, 5, 7, 11}; 12 int n; 13 struct qnode{ 14 int v,c; 15 qnode(int _v=0,int _c=0):v(_v),c(_c){} 16 bool operator < (const qnode &r)const{ 17 return r.c <c; 18 } 19 }; 20 void dij(){ 21 priority_queue<qnode>q; 22 for(int i = 1; i <= n+8; ++i){ 23 d[i] = inf; 24 vis[i] = 0; 25 } 26 d[1]=0; 27 q.push(qnode(1, 0)); 28 while(!q.empty()){ 29 qnode t=q.top(); q.pop(); 30 int u=t.v; 31 if(vis[u]) 32 continue; 33 vis[u]=1; 34 for(int i = 0; i< 4 && u * prime[i] <= n+8; ++i){ 35 int v = u * prime[i]; 36 int w = prime[i]; 37 if(!vis[v] && d[u] + w < d[v]){ 38 d[v] = d[u] + w; 39 q.push(qnode(v, d[v])); 40 } 41 } 42 int v = u - 1; 43 int w = 1; 44 if(!vis[v] && d[u] + w < d[v]){ 45 d[v] = d[u] + w; 46 q.push(qnode(v, d[v])); 47 } 48 } 49 } 50 int main(){ 51 scanf("%d", &n); 52 dij(); 53 printf("%d ", d[n]); 54 return 0; 55 }