zoukankan      html  css  js  c++  java
  • bzoj 1119 [POI2009]SLO && bzoj 1697 [Usaco2007 Feb]Cow Sorting牛排序——思路(置换)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1119

       https://www.lydsy.com/JudgeOnline/problem.php?id=1697

    先找到置换的循环节。发现对于同一个循环节里的元素,可以找一个代价最小的元素,用它把所有元素换到位置上。

    每次交换一定有一个元素到自己的位置上了(不然不优);最后一次是两个元素都弄好了;所以一共是 ( n-1 ) 次。其中,每个元素贡献一次,剩下的 2*(n-1) - n 次贡献就可以选择代价最小的那个元素了。

    还以为这样就是最优的。

    然而其实还可以在循环节外面找一个最小的元素来和自己换。这样的话除了第一次把这个外面的元素换进循环里,剩下每一次交换都有一个元素到了它应该在的位置,所以一共是 ( n+1 ) 次。其中,每个元素贡献一次,被换出去的元素贡献两次,换进来(最后又换出去)的元素贡献 2*(n+1)-n-1 次。和上面情况取 min 即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=1e6+5,M=6505;
    int n,w[N],a[N],b[N],tot; ll ans;
    bool vis[N];
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    ll Mn(ll a,ll b){return a<b?a:b;}
    int main()
    {
      n=rdn();  int tmn=M;
      for(int i=1;i<=n;i++)w[i]=rdn(),tmn=Mn(tmn,w[i]);
      for(int i=1;i<=n;i++)a[i]=rdn();
      for(int i=1;i<=n;i++)b[rdn()]=i;
      for(int i=1;i<=n;i++)
        if(!vis[i])
          {
        int cr=i,mn=M;ll sm=0; tot=0;
        while(!vis[cr])
          {
            tot++; vis[cr]=1;
            mn=Mn(mn,w[a[cr]]); sm+=w[a[cr]];
            cr=b[a[cr]];
          }
        ans+=Mn((ll)mn*(tot-1)+sm-mn,(ll)tmn*(tot+1)+sm+mn);
          }
      printf("%lld
    ",ans);
      return 0;
    }
    View Code
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1e4+5,M=1e5+5;
    int n,a[N],b[N],c[M],ans;
    bool vis[N];
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    int Mn(int a,int b){return a<b?a:b;}
    int main()
    {
      n=rdn(); int tmn=M;
      for(int i=1;i<=n;i++)a[i]=rdn(),tmn=Mn(tmn,a[i]);
      for(int i=1;i<=n;i++)b[i]=a[i];
      sort(b+1,b+n+1);
      for(int i=1;i<=n;i++)c[b[i]]=i;
      for(int i=1;i<=n;i++)
        if(!vis[i])
          {
        int cr=i,tot=0,mn=M,sm=0;
        while(!vis[cr])
          {
            tot++; vis[cr]=1;
            mn=min(mn,a[cr]); sm+=a[cr];
            cr=c[a[cr]];
          }
        ans+=Mn( mn*(tot-1)+sm-mn,tmn*(tot+1)+sm+mn );
          }
      printf("%d
    ",ans);
      return 0;
    }
    View Code
  • 相关阅读:
    bootstrap 学习笔记
    js 学习笔记 -- webpack 简介
    js 学习笔记 -- webapi
    js 学习笔记 -- js基础知识
    css学习笔记二--IFC
    css 学习笔记一
    vim学习笔记
    Linux 网络命令
    Java中循环冗余校验(CRC32)的实现
    Tomcat8启动报there was insufficient free space available after evicting expired cache entries
  • 原文地址:https://www.cnblogs.com/Narh/p/10060000.html
Copyright © 2011-2022 走看看