• 51nod 1693 水群(Dijkstra)


    分析:一开始想暴力dp,但是有环,不好处理。。考虑建一个图,从k向k-1连一条边权为1,向i*k连一条边权i*k的边,然后Dijkstra,复杂度为O(nlogn(loglog(n)),然而这数据范围。。这时间限制。。

    可以简化,只连k乘一个质数p的边,并且p<=13,虽然并不会证明。。可以用未优化过的打个表,发现答案不超过43,因此至少在这个范围内是可行的。。

    Dijkstra一开始常数太大了,因为是把边加进去再做的,可以优化成直接利用点得到边。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<queue>
     5 #include<vector>
     6 using namespace std;
     7 const int maxn=1e6+10;
     8 int pri[100],len=0;
     9 struct Edge{
    10     int from,to,dist;
    11     Edge(int u,int v,int d):from(u),to(v),dist(d){}
    12 };
    13 struct Node{
    14     int d,u;
    15     Node(int d0,int u0):d(d0),u(u0){}
    16 };
    17 bool operator < (Node a,Node b){
    18     return a.d>b.d;
    19 }
    20 struct Dijkstra{
    21     int n;
    22     int d[maxn];
    23     void dijkstra(int s){
    24         priority_queue<Node> q;
    25         for(int i=0;i<n;i++)d[i]=1e9;
    26         d[s]=0;
    27         q.push(Node(0,s));
    28         while(!q.empty()){
    29             Node x=q.top();
    30             q.pop();
    31             int u=x.u;
    32             if(d[u]!=x.d)continue;
    33             for(int i=0;i<len&&pri[i]*u<=n;i++){
    34                 if(d[pri[i]*u]>d[u]+pri[i]){
    35                     d[pri[i]*u]=d[u]+pri[i];
    36                     q.push(Node(d[pri[i]*u],pri[i]*u));
    37                 }
    38             }
    39             if(u>0&&d[u-1]>d[u]+1){
    40                  d[u-1]=d[u]+1;
    41                 q.push(Node(d[u-1],u-1));
    42             }
    43         }
    44     }
    45 }dij;
    46 void CalPri(){
    47     int maxn=14;
    48     bool no_Pri[maxn];
    49     memset(no_Pri,0,sizeof(no_Pri));
    50     for(int i=2;i<maxn;i++){
    51         if(!no_Pri[i]){
    52             pri[len++]=i;
    53         }
    54         for(int j=0;j<len&&pri[j]*i<maxn;j++){
    55             no_Pri[pri[j]*i]=true;
    56             if(i%pri[j]==0)break;
    57         }
    58     }
    59 }
    60 int main(){
    61     CalPri();
    62     int n;
    63     scanf("%d",&n);
    64     dij.n=n+42;
    65     dij.dijkstra(1);
    66     printf("%d
    ",dij.d[n]);
    67     return 0;
    68 }
  • 相关阅读:
    example_php文件上传处理
    andorid SQLite数据库创建文件
    andorid 手机外部储存
    手机界面
    andorid 数据储存、SharedPreferences存储和手机内部储存
    andorid 数据储存
    andorid 多线程handler用法
    andorid 配置器组件和提示消息
    andorid 网格视图GridView
    andorid 列表视图之SimpleAdapter
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7183788.html
Copyright © 2020-2023  润新知