• codeforces #597(div 2)


    A:

    gcd(a,b)==1为有限,否则无限

     1     #include<bits/stdc++.h>
     2     using namespace std;
     3     int T;
     4     int a,b;
     5     int gcd(int a,int b)
     6     {
     7         if(!b)return a;
     8         return gcd(b,a%b);
     9     }
    10     int main()
    11     {
    12         scanf("%d",&T);
    13         while(T--)
    14         {
    15             scanf("%d%d",&a,&b);
    16             if(gcd(a,b)!=1)puts("Infinite");
    17             else puts("Finite");
    18         }
    19     }
    View Code

    B:

    贪心地模拟一下

     1     #include<bits/stdc++.h>
     2     using namespace std;
     3     int T,n,a,b,c;
     4     char s[105],Ans[105];
     5     int main()
     6     {
     7         scanf("%d",&T);
     8         while(T--)
     9         {
    10             scanf("%d%d%d%d",&n,&a,&b,&c);
    11             scanf("%s",s+1);
    12             memset(Ans,0,sizeof(Ans));
    13             int ans=0;
    14             for(int i=1;i<=n;++i)
    15             {
    16                 if(s[i]=='R'&&b>0)Ans[i]='P',b--,ans++;
    17                 if(s[i]=='P'&&c>0)Ans[i]='S',c--,ans++;
    18                 if(s[i]=='S'&&a>0)Ans[i]='R',a--,ans++;
    19             }
    20             if(ans>=(n+1)/2)
    21             {
    22                 puts("YES");
    23                 for(int i=1;i<=n;++i)if(!Ans[i])
    24                 {
    25                     if(a)Ans[i]='R',a--;
    26                     else if(b)Ans[i]='P',b--;
    27                     else Ans[i]='S',c--;
    28                 }
    29                 printf("%s
    ",Ans+1);
    30             }
    31             else puts("NO");
    32         }
    33     }
    View Code

    C:

    先判一下有w或者m为0

    发现每个u和n形成的连续段答案可以递推,递推式为斐波拉契

    然后预处理斐波拉契取出所有连续段,方案数相乘

     1     #include<bits/stdc++.h>
     2     #define maxn 100005
     3     using namespace std;
     4     const int mod = 1000000007;
     5     int n;
     6     char s[maxn];
     7     vector<int> A;
     8     int dp[maxn];
     9     int main()
    10     {
    11         scanf("%s",s+1);
    12         n=strlen(s+1);
    13         dp[0]=dp[1]=1;
    14         for(int i=1;i<=n;++i)dp[i]=(dp[i-1]+dp[i-2])%mod;
    15         for(int i=1;i<=n;++i)if(s[i]=='w'||s[i]=='m'){puts("0");return 0;}
    16         int len=0;
    17         for(int i=1;i<=n;++i)
    18         {
    19             if(s[i]=='u')
    20             {
    21                 if(s[i-1]=='u')len++;
    22                 else
    23                 {
    24                     if(len)A.push_back(len);
    25                     len=1;
    26                 }
    27             }
    28             else if(s[i]=='n') 
    29             {
    30                 if(s[i-1]=='n')len++;
    31                 else
    32                 {
    33                     if(len)A.push_back(len);
    34                     len=1;
    35                 } 
    36             }
    37             else
    38             {
    39                 if(len)A.push_back(len);
    40                 len=0;
    41             }
    42         }
    43         if(len)A.push_back(len);
    44         int ans=1;
    45         for(auto len: A)ans=1ll*ans*dp[len]%mod;
    46         printf("%d
    ",ans);
    47     }
    View Code

    D:

    超级根向每个点连边,权值为c[i]

    点与点之间连边,权值为(k[i]+k[j])*dis(i,j)

    最小生成树

     1     #include<bits/stdc++.h>
     2     #define ll long long
     3     #define maxn 2005
     4     using namespace std;
     5     int n;
     6     ll X[maxn],Y[maxn],c[maxn],k[maxn];
     7     struct edge
     8     {
     9         int u,v;
    10         ll w;
    11         edge(int U=0,int V=0,ll W=0):u(U),v(V),w(W){} 
    12     }e[maxn*maxn];
    13     int fa[maxn];
    14     bool operator < (edge A,edge B){return A.w<B.w;}
    15     int find(int x)
    16     {
    17         if(fa[x]==x)return x;
    18         return fa[x]=find(fa[x]);
    19     }
    20     vector<int> A;
    21     vector< pair<int,int> >B;
    22     int main()
    23     {
    24         scanf("%d",&n);
    25         for(int i=1;i<=n;++i)scanf("%I64d%I64d",&X[i],&Y[i]);
    26         for(int i=1;i<=n;++i)scanf("%I64d",&c[i]);
    27         for(int i=1;i<=n;++i)scanf("%I64d",&k[i]);
    28         int cnt=0;
    29         for(int i=0;i<=n;++i)fa[i]=i;
    30         for(int i=1;i<=n;++i)e[++cnt]=edge(0,i,c[i]);
    31         for(int i=1;i<=n;++i)
    32             for(int j=1;j<=n;++j)if(i!=j)e[++cnt]=edge(i,j,(k[i]+k[j])*(abs(X[i]-X[j])+abs(Y[i]-Y[j])));
    33         sort(e+1,e+cnt+1);
    34         ll ans=0;
    35         for(int i=1;i<=cnt;++i)
    36         {
    37             int u=e[i].u,v=e[i].v;
    38             if(find(u)==find(v))continue;
    39             fa[find(v)]=find(u);
    40             ans+=e[i].w;
    41             if(!u)A.push_back(v);
    42             else B.push_back(make_pair(u,v)); 
    43         }
    44         printf("%I64d
    ",ans);
    45         printf("%d
    ",A.size());
    46         for(auto p: A)printf("%d ",p);
    47         puts("");
    48         printf("%d
    ",B.size());
    49         for(auto p: B)printf("%d %d
    ",p.first,p.second);
    50         
    51     }
    View Code

    E:

    期望DP

    预处理出来每个位置的下一步是哪个点

    然后记忆化搜一下就好了

     1     #include<bits/stdc++.h>
     2     using namespace std;
     3     int a[12][12];
     4     double dp[12][12];
     5     bool vis[12][12];
     6     int nx[12][12],ny[12][12];
     7     double dfs(int x,int y)
     8     {
     9         if(vis[x][y])return dp[x][y];
    10         vis[x][y]=1;
    11         if(x==1&&y==1)return dp[x][y]=0;
    12         double res=0;
    13         int px=x,py=y;
    14         int num=6;
    15         for(int k=1;k<=6;++k)
    16         {
    17             int xx=nx[px][py],yy=ny[px][py];
    18             px=xx;py=yy;
    19             if(!px||!py)--num;
    20             else res+=min(dfs(px,py),dfs(px-a[px][py],py))/6.0;
    21         }
    22         dp[x][y]=(res+1.0)*6.0/(double)num;
    23         return dp[x][y];
    24     }
    25     int main()
    26     {
    27         for(int i=1;i<=10;++i)
    28             for(int j=1;j<=10;++j)cin>>a[i][j];
    29         for(int i=10;i>=1;--i)
    30         {
    31             if(i&1)
    32             {
    33                 for(int j=10;j>=2;--j)nx[i][j]=i,ny[i][j]=j-1;
    34                 nx[i][1]=i-1;ny[i][1]=1;
    35             }
    36             else
    37             {
    38                 for(int j=1;j<=9;++j)nx[i][j]=i,ny[i][j]=j+1;
    39                 nx[i][10]=i-1;ny[i][10]=10;
    40             }
    41         }
    42         for(int i=1;i<=10;++i)
    43             for(int j=1;j<=10;++j)dp[i][j]=1e9;
    44         printf("%.10f
    ",dfs(10,1));
    45     }
    View Code

    F:

    数位DP

    先把问题容斥成(1,n,1,m)的形式

    然后考虑状态为dp(len,0/1,0/1,lim1,lim2):在第len位,第一个是0/1,第二个是0/1,第一个贴不贴上界,第二个贴不贴上界

    然后 a xor b = a+b就是每位都不产生进位

    那么不能出现1 1这种情况

    dp一下就好了

     1     #include<bits/stdc++.h>
     2     #define ll long long
     3     using namespace std;
     4     int T;
     5     ll l,r;
     6     ll a[35],b[35];
     7     ll fastpow(ll a,ll p)
     8     {
     9         ll ans=1;
    10         while(p)
    11         {
    12             if(p&1)ans=ans*a;
    13             a=a*a;p>>=1;
    14         }
    15         return ans;
    16     }
    17     ll dp[35][2][2][2][2];
    18     bool vis[35][2][2][2][2];
    19     ll dfs(ll len,ll x,ll y,ll lim1,ll lim2)
    20     {
    21         if(!len)return 1;
    22         if(vis[len][x][y][lim1][lim2])return dp[len][x][y][lim1][lim2];
    23         vis[len][x][y][lim1][lim2]=1;
    24         ll res=0;
    25         if(a[len-1]==1&&b[len-1]==1)
    26         {
    27             res+=dfs(len-1,0,1,0,lim2)+dfs(len-1,1,0,lim1,0)+dfs(len-1,0,0,0,0);
    28         }
    29         else if(a[len-1]==1)
    30         {
    31             res+=dfs(len-1,0,0,0,lim2)+dfs(len-1,1,0,lim1,lim2);
    32             if(!lim2)res+=dfs(len-1,0,1,0,0);
    33         }
    34         else if(b[len-1]==1)
    35         {
    36             res+=dfs(len-1,0,0,lim1,0)+dfs(len-1,0,1,lim1,lim2);
    37             if(!lim1)res+=dfs(len-1,1,0,0,0);
    38         }
    39         else
    40         {
    41             res+=dfs(len-1,0,0,lim1,lim2);
    42             if(!lim1)res+=dfs(len-1,1,0,0,lim2);
    43             if(!lim2)res+=dfs(len-1,0,1,lim1,0);
    44         }
    45         return dp[len][x][y][lim1][lim2]=res;
    46     }
    47     ll solve(ll x,ll y)
    48     {
    49         memset(a,0,sizeof(a));
    50         memset(b,0,sizeof(b));
    51         memset(dp,0,sizeof(dp));
    52         memset(vis,0,sizeof(vis));
    53         for(int i=30;i>=0;--i)a[i]=(x>>i)&1,b[i]=(y>>i)&1;
    54         ll ans=dfs(31,0,0,1,1);
    55         return ans;
    56     }
    57     int main()
    58     {
    59         cin>>T;
    60         while(T--)
    61         {
    62             cin>>l>>r;
    63             if(l>0)cout<<solve(r,r)-solve(r,l-1)-solve(l-1,r)+solve(l-1,l-1)<<endl;
    64             else cout<<solve(r,r)<<endl;
    65         }
    66     }
    View Code
  • 相关阅读:
    HDU 2795
    HDU 1394
    HDU 1754
    HDU 1166
    SDOI 2006
    HDU 1423
    HDU 1561
    centos7.4 搭建zabbix-server 3.4.5
    vim 简单笔记
    jdk环境并配置环境变量
  • 原文地址:https://www.cnblogs.com/uuzlove/p/11780601.html
Copyright © 2020-2023  润新知