• 训练日志4 (7.16)


    T1 礼物

      一道既不是很水其实又很水的题,n<=20,显然的状压。

      定义f[i]为在i状态下的期望购买次数(0表示没买,1表示已经买了),题出的很毒瘤,0<pi<=1,所以不存在有的礼物买不到的情况,又简单了(可是我还是没有想到)。

      然后状态转移其实很好理解,i状态可能是从i'转移而来,也可能是从它本身转移过来,这就是买与不买的问题。

      f[i]=Σ(f[i']*p[j])+f[i]*(1-Σp[j]) (注意反推,从结果开始向后推,这样才能使Σp[j]有意义,正推不好求买到重复和不买的情况)

      解释也很简单:每个物品j有p[j]的概率选中,转移到f[i]的总期望次数显然是其加和的结果,还可以从本身转移,概率就是其他物品都不选的情况了。

      注意一下和的处理,这道题差不多就结束了(skyh神仙15minAC)。

      小弟不才。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #define HZOI using namespace std
     5 HZOI;
     6 double p[25];
     7 long long w[25];
     8 int n;
     9 double f[(1<<22)];
    10 int main()
    11 {
    12     long long ans=0;
    13     scanf("%d",&n);
    14     for (int i=1; i<=n; ++i)
    15     {
    16         scanf("%lf%lld",&p[i],&w[i]);
    17         ans+=w[i];
    18     }
    19     for (int i=1; i<(1<<n); ++i)
    20     {
    21         double P=0,F=0;
    22         for (int j=i; j; j-=j&(-j))
    23         {
    24             int k=j&(-j);
    25             P+=p[(int)log2(k)+1];
    26             F+=f[i^k]*p[(int)log2(k)+1];
    27         }
    28         f[i]=(F+1)/P;
    29     }
    30     printf("%lld
    %.3lf
    ",ans,f[(1<<n)-1]);
    31     return 0;
    32 }
    礼物

     

    T2 通讯

      板子题,只能这么定义它了。

      10%很好拿,直接边权相加,即为最终答案。

      正解Tarjan缩点,然后……枚举每一条边,找入边边权最小的一条作为树边,问题就这么被很好的解决了。

      题目有个坑就是很容易让人想到最小生成树(Kruskal算法),然后光荣的10分,这正是坑人的地方(还好我不会打最小生成树哈哈哈~),这种算法只适用于无向边的遍历找最小,如果是有向边,很可能生成的就不是一棵树了(也就是说从根节点不能到达所有的子节点),这就是算法的问题,但是同样是最小生成树的Prim算法应该可以实现有向图的遍历,目前还没有实现出来。

      最后,注意,多测要清空。

      小弟不才。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<queue>
     6 #define HZOI using namespace std
     7 HZOI;
     8 int n,m;
     9 int num,tt,vv[300003],first[300003],nx[300003],ww[300003];
    10 int tail,tot,dfn[100003],low[100003],be[100003],stack[100003],dis[100003];
    11 long long ans;
    12 bool vis[100003];
    13 inline void Add(int ,int ,int );
    14 void Tarjan(int );
    15 inline void Clear();
    16 void Work();
    17 int main()
    18 {
    19     while (scanf("%d%d",&n,&m)==2)
    20     {
    21         if (!n and !m) break;
    22         Clear();
    23         for (int i=1; i<=m; ++i)
    24         {
    25             int u,v,w;
    26             scanf("%d%d%d",&u,&v,&w);
    27             Add(u,v,w);
    28         }
    29         Tarjan(0);
    30         for (int i=0; i<n; ++i) vis[i]=0;
    31         memset(dis,0x3f3f3f3f,sizeof(dis));
    32         dis[0]=0;
    33         for (int i=0; i<n; ++i)
    34             if (!vis[be[i]])
    35             {
    36                 for (int j=first[be[i]]; j; j=nx[j])
    37                     if (be[vv[j]]!=be[i])
    38                         {dis[be[vv[j]]]=min(dis[be[vv[j]]],ww[j]);}
    39                 vis[be[i]]=1;
    40             }
    41         for (int i=0; i<n; ++i) vis[i]=0;
    42         for (int i=0; i<n; ++i)
    43             if (!vis[be[i]])
    44                 {ans+=dis[be[i]];vis[be[i]]=1;}
    45         printf("%lld
    ",ans);
    46     }
    47     return 0;
    48 }
    49 void Tarjan(int k)
    50 {
    51     dfn[k]=low[k]=++tot;
    52     stack[++tail]=k;
    53     vis[k]=1;
    54     for (int i=first[k]; i; i=nx[i])
    55     {
    56         int ver=vv[i];
    57         if (!dfn[ver])
    58         {
    59             Tarjan(ver);
    60             low[k]=min(low[k],low[ver]);
    61         }
    62         if (vis[ver]) low[k]=min(low[k],dfn[ver]);
    63     }
    64     if (dfn[k]==low[k])
    65     {
    66         int to;
    67         ++num;
    68         do
    69         {
    70             to=stack[tail--];
    71             be[to]=k;
    72             vis[to]=0;
    73             for (int i=first[to]; i; i=nx[i])
    74                 Add(be[to],vv[i],ww[i]);
    75         } while (to!=k);
    76     }
    77 }
    78 inline void Add(int u,int v,int w)
    79 {
    80     vv[++tt]=v; ww[tt]=w; nx[tt]=first[u]; first[u]=tt;
    81 }
    82 inline void Clear()
    83 {
    84     memset(vv,0,sizeof(vv));
    85     memset(first,0,sizeof(first));
    86     memset(nx,0,sizeof(nx));
    87     memset(ww,0,sizeof(ww));
    88     memset(vis,0,sizeof(vis));
    89     memset(dis,0,sizeof(dis));
    90     memset(dfn,0,sizeof(dfn));
    91     memset(low,0,sizeof(low));
    92     memset(be,0,sizeof(be));
    93     memset(stack,0,sizeof(stack));
    94     tail=tot=num=tt=ans=0;
    95 }
    通讯

      

    T3 奇袭

      神仙题。

      考试暴力n4怒拿27。

      正解分治+单调栈优化。

      首先第一步,理解题意,接着转化题意。

      因为每个点都在不同行的不同列,所以我们可以转化成:给定N个数的一个排列,问这个序列中有多少个子区间的数恰好是连续的

      然后n2算法就出来了:枚举每一个区间大小size,再枚举每一个起点i,记录最大值最小值,若max-min=size-1,则是合法的,67分

      据机房巨佬们说,n2算法加上一些神奇的剪枝,可以卡到91分,这性价比已经很高了。

      天知道这能优化到nlogn

      我们分治每个区间,为[l~mid],[mid+1~r],然后就可以分情况讨论:

      1.最大值最小值在同侧。

      2.最大值最小值在异侧。

      先从中间开始向两边扩展,计算每个点到中间的最值。

      同侧情况比较好处理,枚举每一个左边界位置,通过max-min=r-l可以判断右边界位置,如果对应位置的条件合法(即max和min均在同侧),则ans++。

      然后就是不同侧处理。

      记住不能用memset,150000的数组足够把一个AC代码卡成64了。

      小弟不才。

      

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define HZOI using namespace std
     5 HZOI;
     6 const int N=50003;
     7 int a[50003],stack[50003];
     8 int n,cnt,res;
     9 int lmin[50003],lmax[50003],rmin[50003],rmax[50003],t[3*50003];
    10 int Work(int ,int );
    11 int Go_on(int ,int ,int );
    12 inline int read();
    13 int main()
    14 {
    15     n=read();
    16     for (int i=1; i<=n; ++i)
    17         {int x; x=read(); a[x]=read();}
    18     res=Work(1,n);
    19     printf("%d
    ",res);
    20 }
    21 int Work(int l,int r)
    22 {
    23     if (l==r) return 1;
    24     int mid=(l+r)>>1;
    25     int ans=Work(l,mid)+Work(mid+1,r);
    26     ans+=Go_on(l,r,mid);
    27     return ans;
    28 }
    29 int Go_on(int l,int r,int mid)
    30 {
    31     int ans=0;
    32     lmin[mid]=lmax[mid]=a[mid];
    33     rmin[mid+1]=rmax[mid+1]=a[mid+1];
    34     for (int i=mid-1; i>=l; --i)
    35         {lmin[i]=min(lmin[i+1],a[i]); lmax[i]=max(lmax[i+1],a[i]);}
    36     for (int i=mid+2; i<=r; ++i)
    37         {rmin[i]=min(rmin[i-1],a[i]); rmax[i]=max(rmax[i-1],a[i]);}
    38     for (int i=mid; i>=l; --i) 
    39         {int to=i+lmax[i]-lmin[i]; if (to>mid and to<=r and rmin[to]>lmin[i] and rmax[to]<lmax[i]) ++ans;}
    40     for (int i=mid+1; i<=r; ++i)
    41         {int to=i-rmax[i]+rmin[i]; if (to<=mid and to>=l and lmin[to]>rmin[i] and lmax[to]<rmax[i]) ++ans;}
    42     int p=mid,q=mid;
    43     while (lmin[p]>rmin[r] and p>=l) {t[lmax[p]+p+N]++; --p;}  //left max
    44     while (lmax[q]<rmax[r] and q>=l) {t[lmax[q]+q+N]--; --q;}  //right min
    45     for (int i=r; i>mid; --i)
    46     {
    47         while (lmin[p+1]<rmin[i] and p<mid) {++p; t[lmax[p]+p+N]--;}
    48         while (lmax[q+1]>rmax[i] and q<mid) {++q; t[lmax[q]+q+N]++;}
    49         if (t[rmin[i]+i+N]>0) {ans+=t[rmin[i]+i+N];}
    50     }
    51     for (int i=l; i<=mid; ++i) t[lmax[i]+i+N]=0;
    52     p=mid+1; q=mid+1;
    53     while (rmax[q]<lmax[l] and q<=r) {t[rmax[q]-q+N]--; ++q;}  //right max 
    54     while (rmin[p]>lmin[l] and p<=r) {t[rmax[p]-p+N]++; ++p;}  //left min  
    55     for (int i=l; i<=mid; ++i)
    56     {
    57         while (rmin[p-1]<lmin[i] and p>mid+1) {--p; t[rmax[p]-p+N]--;}
    58         while (rmax[q-1]>lmax[i] and q>mid+1) {--q; t[rmax[q]-q+N]++;}
    59         if (t[lmin[i]-i+N]>0) {ans+=t[lmin[i]-i+N];}
    60     }
    61     for (int i=mid+1; i<=r; ++i) t[rmax[i]-i+N]=0;
    62     return ans;
    63 }
    64 inline int read()
    65 {
    66     int num=0; char ch=getchar();
    67     while (ch<'0' or ch>'9') ch=getchar();
    68     while (ch>='0' and ch<='9') num=(num<<3)+(num<<1)+(ch-48),ch=getchar();
    69     return num;
    70 }
    奇袭

      

      永不放弃。

  • 相关阅读:
    浅谈REST[转]
    linuxyum
    XAMPPAccess denied for user 'root'@'localhost' (using password:YES)....& can't connect to localhost...
    ps aux详细解释【转】
    TOP 10:值得关注的十家云计算公司【转】
    isnull在数据库查询中的应用
    正则匹配代码
    推荐一款生成SQL插入语句的软件
    网页自动刷新
    执行SQL脚本语句判断是否已经存在
  • 原文地址:https://www.cnblogs.com/LH-Xuanluo/p/11200219.html
Copyright © 2020-2023  润新知