zoukankan      html  css  js  c++  java
  • 51-Nod 1693 水群

                                                              1693 水群

    总所周知,水群是一件很浪费时间的事,但是其实在水群这件事中,也可以找到一些有意思的东西。
    比如现在,bx2k就在研究怎样水表情的问题。
    首先,bx2k在对话框中输入了一个表情,接下来,他可以进行三种操作。
    第一种,是全选复制,把所有表情全选然后复制到剪贴板中。
    第二种,是粘贴,把剪贴板中的表情粘贴到对话框中。
    第三种,是退格,把对话框中的最后一个表情删去。
    假设当前对话框中的表情数是num0,剪贴板中的表情数是num1,
    那么第一种操作就是num1=num0
    第二种操作就是num0+=num1
    第三种操作就是num0--
    现在bx2k想知道,如果要得到n(1<=n<=10^6)个表情,最少需要几次操作。
    请你设计一个程序帮助bx2k水群吧。
    Input
    一个整数n表示需要得到的表情数
    Output
    一个整数ans表示最少需要的操作数
    Input示例
    233
    Output示例
    17


    三种操作
    一是复制 二是粘贴 三是删除
    当前有一个表情
    复制 粘贴 粘贴 就有三个表情了 一共三次操作
    若有两个表情
    复制 粘贴 粘贴 就有6个表情 三次操作 得到 2*3个表情
    那么 我们可以把 第一和第二个操作合并 看成一个操作
    当前有 a 个表情 可以经过 k次操作 变成a*k个表情

    还有一个操作就是删除 没什么好说的

    题目要让求 1变成 n 的最小次数 那么 这就是一个最短路模型

    通过上面的操作 我们可以这样建图
    i->i*k 操作次数为 k
    i->i-1 操作次数为 1

    但是复杂度太高 并不能在0.4s内通过

    我们可以发现 1->6 有一条边
    2->6 也会有一条边
    注意到如果一条边i→i*k能用若干条边代替
    那么i→i*k这条边就是没有意义的
    因为那些边的权值的乘积等于k
    即那些边的权值和小于等于k
    所以 我们可以替换许多没有用的边 
    因此对于每个i,只用连i→i*p的边,其中p是质数

    这个时候 0.4s差不多了 但是题目之前时限是 0.1s (后来改为0.4s)
    所以我们记录最短路的路径 发现最有质数p<=13时才有意义
    0.4s 无压力 但是0.1s还不行 需要用dp (我并不会T_T)

     1 #include <queue>
     2 #include <cstdio>
     3 #include <cctype>
     4 #include <cstring>
     5 
     6 const int INF=0x3f3f3f3f;
     7 const int MAXN=1000010;
     8 
     9 int n;
    10 
    11 int dis[MAXN],q[MAXN],prim[11]={0,2,3,5,7,9,11,13};
    12 
    13 bool vis[MAXN];
    14 
    15 inline void read(int&x) {
    16     int f=1;register char c=getchar();
    17     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
    18     for(;isdigit(c);x=x*10+c-48,c=getchar());
    19     x=x*f;
    20 }
    21 
    22 inline int min(int a,int b) {return a<b?a:b;}
    23 
    24 int hh() {
    25     read(n);
    26     memset(dis,INF,sizeof dis);
    27     int head=0,tail=0;
    28     q[++tail]=1;
    29     dis[1]=0;
    30     while(head!=tail) {
    31         int u=q[++head];
    32         vis[u]=false;
    33         if(head==MAXN) head=0;
    34         for(int i=1;i<=7;++i) {
    35             int v=u*prim[i];
    36             if(v>n+20) break;
    37             if(v<n+20&&dis[v]>dis[u]+prim[i]) {
    38                 dis[v]=dis[u]+prim[i];
    39                 if(!vis[v]) {
    40                     vis[v]=true;
    41                     q[++tail]=v;
    42                     if(tail==MAXN) tail=0;
    43                 }
    44             }
    45         }
    46         if(u&&dis[u-1]>dis[u]+1) {
    47             dis[u-1]=dis[u]+1;
    48             if(!vis[u-1]) {
    49                 vis[u-1]=true;
    50                 q[++tail]=u-1;
    51                 if(tail==MAXN) tail=0;
    52             }
    53         }
    54     }
    55     printf("%d
    ",dis[n]);
    56     return 0;
    57 }
    58 
    59 int sb=hh();
    60 int main(int argc,char**argv) {;}
    SPFA代码


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    爬虫
    Django
    python多线程
    python基础
    深度学习_1_Tensorflow_1
    人工智能_5_决策树_随机森林
    人工智能_4_k近邻_贝叶斯_模型评估
    人工智能_3_机器学习_概述
    Python re 模块
    Python函数式编程
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7511227.html
Copyright © 2011-2022 走看看