• 17-10-18模拟赛


    T1:

    固定一个方向的刀数的时候,平均切时答案最大。
    可以发现,如果能够只切一边,只切一边一定最优。
    当n<=m,k>=m时,考虑将一边全部切开,剩下的平均切到另一边。
    因为n/(k-(n-1))>=m/(k-(m-1)),所以长边切m-1刀,短边切k-(m-1)刀一定最优。

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define ll long long
     5 using namespace std;
     6 inline ll in(){
     7     ll x=0;bool f=0; char c;
     8     for (;(c=getchar())<'0'||c>'9';f=c=='-');
     9     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
    10     return f?-x:x;
    11 }
    12 ll n,m,k;
    13 int main()
    14 {
    15     n=in();m=in();k=in();
    16     if (n<m) swap(n,m);
    17     if (k>n+m-2) {printf("-1");return 0;}
    18     if (k<m) printf("%lld",max((m/(k+1))*n,(n/(k+1))*m));
    19     else if (k<n) printf("%lld",max(n/(k-m+2),(n/(k+1))*m));
    20     else printf("%lld",max(n/(k-m+2),m/(k-n+2)));return 0;
    21 }

    T2:注意到ai不超过30,所以选择的bi小于59,否则选择1一定不劣。

    注意到58以内只有16个质数,考虑将选择这些质数的状态压缩后dp即可,时间复杂度O(2^16*n*58).

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define inf 0x3f3f3f3f
     5 #define MN 102
     6 #define Range 59
     7 #define Rp 16
     8 using namespace std;
     9 inline int in(){
    10     int x=0;bool f=0; char c;
    11     for (;(c=getchar())<'0'||c>'9';f=c=='-');
    12     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
    13     return f?-x:x;
    14 }
    15 const int pri[16]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
    16 int f[MN][(1<<Rp)],pre[MN][(1<<Rp)],a[MN],s[Range],st[MN];
    17 int n,mn=inf,p=0;
    18 int main()
    19 {
    20     n=in();for (int i=1;i<=n;++i) a[i]=in();
    21     memset(f,0x3f,sizeof(f));f[0][0]=0;
    22     for (int i=1;i<Range;++i)
    23     for (int j=0;j<Rp;++j) if (!(i%pri[j])) s[i]|=(1<<j);
    24     for (int i=1;i<=n;++i)
    25     for (int j=0;j<(1<<Rp);++j)
    26     for (int k=1;k<Range;++k)
    27     if (!(j&s[k])&&f[i][j|s[k]]>f[i-1][j]+abs(a[i]-k)) 
    28     f[i][j|s[k]]=f[i-1][j]+abs(a[i]-k),pre[i][j|s[k]]=k;
    29     for (int i=0;i<(1<<Rp);++i) if (f[n][i]<mn) mn=f[n][i],p=i;
    30     for (int i=n;i;p^=s[pre[i][p]],--i) st[i]=pre[i][p];
    31     for (int i=1;i<=n;++i) printf("%d ",st[i]);return 0;
    32 }

    T3:对新加边去重,对于每个点的边只保留边权最小的边,然后做最短路。

    一条新加边如果长度不是到该点最短路的长度一定可以去掉,否则只有满足有其它最短路径到达这个点的时候才可以去掉。

    因此算出到每个点最短路条数是否大等于2即可。

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 #define mp(x,y) make_pair(x,y)
     6 #define ll long long
     7 #define inf 0x3f3f3f3f
     8 #define ME 500005
     9 #define MN 50005
    10 using namespace std;
    11 inline int in(){
    12     int x=0;bool f=0; char c;
    13     for (;(c=getchar())<'0'||c>'9';f=c=='-');
    14     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
    15     return f?-x:x;
    16 }
    17 struct edge{
    18     int to,next;
    19     ll val;
    20 }e[ME];
    21 int head[MN],num[MN],n,m,k,s,u,v,cnt=0,res;
    22 ll dis[MN],dst[MN],t,w;
    23 inline void ins(int x,int y,ll v){
    24     e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt;e[cnt].val=v;
    25 }
    26 typedef pair<ll,int> pr;
    27 inline void dij(int s){
    28     priority_queue<pr,vector<pr>,greater<pr> > q;
    29     memset(dis,0x3f,sizeof(dis));
    30     dis[s]=0ll;q.push(mp(0ll,s));
    31     while (!q.empty()){
    32         pr x=q.top();int u=x.second;q.pop();
    33         if (dis[u]<x.first) continue;
    34         for (int i=head[u];i;i=e[i].next){
    35             int v=e[i].to;
    36             if (dis[v]>dis[u]+e[i].val){
    37                 dis[v]=dis[u]+e[i].val;
    38                 q.push(mp(dis[v],v));num[v]=num[u];
    39             }else if (dis[v]==dis[u]+e[i].val) num[v]=min(num[u]+num[v],inf);
    40         }
    41     }
    42 }
    43 int main()
    44 {
    45     n=in();m=in();k=in();
    46     for (int i=1;i<=m;++i){
    47         u=in();v=in();scanf("%lld",&t);
    48         ins(u,v,t);ins(v,u,t);
    49     }for (int i=1;i<=k;++i){
    50         s=in();scanf("%lld",&w);
    51         if (dst[s]) ++res,dst[s]=min(dst[s],w);
    52         else dst[s]=w;
    53     }for (int i=2;i<=n;++i)
    54     if (dst[i]) ins(1,i,dst[i]),ins(i,1,dst[i]);dij(1);
    55     for (int i=2;i<=n;++i){
    56         if (dst[i]&&(dis[i]<dst[i]||(dis[i]==dst[i]&&num[i]>1))) ++res;
    57     }printf("%d",res);return 0;
    58 }
  • 相关阅读:
    R语言爬虫:CSS方法与XPath方法对比(代码实现)
    R语言爬虫:Rvest包函数介绍(表格)
    R语言爬虫:使用R语言爬取豆瓣电影数据
    R语言学习笔记(二十二):字符串处理中的函数对比(代码实现)
    R语言学习笔记(二十一):字符串处理中的元字符(代码展示)
    history命令详解
    文件服务器:FTP服务器详解
    Linux下的DOS攻击
    Linux-/proc目录简介
    Linux-详解inode节点
  • 原文地址:https://www.cnblogs.com/codingutopia/p/test171018.html
Copyright © 2020-2023  润新知