zoukankan      html  css  js  c++  java
  • 2017 国庆湖南Day2

    期望得分:100+30+100=230

    实际得分:100+30+70=200

    T3 数组开小了 。。。。。

    记录 1的前缀和,0的后缀和

    枚举第一个1的出现位置

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    #define N 100002
    
    using namespace std;
    
    char s[N];
    
    int num[N];
    
    int suf0[N],pre1[N];
    
    int main()
    {
        freopen("reverse.in","r",stdin);
        freopen("reverse.out","w",stdout);
        scanf("%s",s+1);
        int len=strlen(s+1);
        for(int i=1;i<=len;i++) num[i]=s[i]-'0';
        for(int i=1;i<=len;i++) pre1[i]=pre1[i-1]+num[i];
        for(int i=len;i;i--) suf0[i]=suf0[i+1]+(!num[i]);
        int ans=len;
        for(int i=1;i<=len;i++) ans=min(ans,pre1[i-1]+suf0[i]);
        ans=min(ans,pre1[len]);
        printf("%d",ans);
    }
    View Code

    从1——n枚举一遍

    二进制表示它有哪些数出现过了,相当于哈希

    然后Σ C(i,2)

    #include<cstdio>
    
    using namespace std;
    
    int  f[1026];
    
    void count(int x)
    {
        int s=0;
        while(x)
        {
            s|=1<<x%10;
             x/=10;
        }
        f[s]++;
    }
    
    int main()
    {
        freopen("number.in","r",stdin);
        freopen("number.out","w",stdout); 
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) count(i);
        long long ans=0;
        for(int i=1;i<=1023;i++) ans+=1ll*f[i]*(f[i]-1)/2;
        printf("%I64d",ans);
    }
    View Code

    考场思路:

    种类只有2^9种可能

    所以枚举每一种可能

    那问题转化为了 有x种数,用它来组成<=n的数的方案数

    开始想裸的数位DP,但它不能保证所有的x种数都用上

    然后又改的状压DP,dp[i][j] 表示填了i位,使用数的状态为j,

    虽然能保证所有的x种数都用上,但数位DP的作用难以体现:

    若枚举这一位填哪个数,因为不知道前面填了什么,所以也不能确定这一位填什么

    脑补的改进方法是 数位DP加一维表示状态,状压DP加一维表示上一位填了什么

    可行性未知

    考场错误的状压DP

    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    int tmp[10],num[10];
    
    int use[10],dp[10][1024];
    int a[10],b[10];
    
    int main()
    {
        int n,len=0;
        scanf("%d",&n); 
        if(n<10) { printf("0"); return 0; }
        while(n) { tmp[++len]=n%10; n/=10;} 
        for(int i=len,len=0;i;i--) num[++len]=tmp[i];
        int tot,sum,T; long long ans=0;
        num[0]=10;
        for(int s=2;s<1023;s++)
        {
            if(s==2)
            {
                int sad=4;
            }
            memset(use,false,sizeof(use)); tot=0;
            memset(b,0,sizeof(b));
            memset(dp,0,sizeof(dp)); 
            for(int i=0;i<10;i++) if(s&(1<<i)) tot++,use[i]=true,b[i]=tot;
            T=1<<tot; 
            for(int i=1;i<=tot;i++) dp[1][1<<i-1]=1;
            for(int i=1;i<len;i++)
                for(int t=T-1;t;t=t&(t-1))
                    for(int j=0;j<=num[i+1];j++) 
                        if(use[j]) dp[i+1][t|1<<b[j]-1]+=dp[i][t];
            tot=0;
            
            for(int i=1;i<=len;i++)  tot+=dp[i][T-1];
            ans+=1ll*tot*(tot-1)/2;
            if(tot) printf("%d %d
    ",s,tot);
        }
        printf("%I64d
    ",ans);
    }
    View Code

    考场错误的数位DP

    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    int tmp[10],num[10];
    
    int dp[10][10][10][2];
    bool use[10];
    
    int main()
    {
        int n,len=0;
        scanf("%d",&n); 
        if(n<10) { printf("0"); return 0; }
        while(n) { tmp[++len]=n%10; n/=10;} 
        for(int i=len,len=0;i;i--) num[++len]=i;
        int S=1<<10; long long tot,ans=0;
        for(int s=S-1;s;s=s&(s-1))
        {
            memset(use,false,sizeof(use));
            memset(dp,0,sizeof(dp));
            for(int i=0;i<10;i++) 
              if(s&(1<<i)) use[i]=true;
            for(int i=1;i<10;i++) dp[1][i][0]=1;
            for(int i=1;i<len;i++)
                for(int j=0;j<10;j++)
                    for(int k=0;k<2;k++)
                        if(k)
                            for(int l=0;l<=num[i];l++) dp[i+1][l][1]+=dp[i][j][1];
                        else
                            for(int l=0;l<10;l++)
                                if(l==num[i]) dp[i+1][l][1]+=dp[i][j][0];
                                else dp[i+1][l][0]+=dp[i][j][0];
            tot=0;
            for(int i=1;i<=len;i++) 
                for(int j=0;j<10;j++)
                {
                    tot+=dp[i][j][0]+dp[i][j][1];
                    printf("%d %d
    ",dp[i][j][0],dp[i][j][1]);
                }
                 
            ans+=tot*(tot+1)/2;
        }
        printf("%I64d
    ",ans);
    }
    View Code

    30暴力

    #include<cstdio>
    #include<cstring>
    
    bool visx[10];
    bool visy[10];
    
    using namespace std;
    
    int main()
    {
        freopen("number.in","r",stdin);
        freopen("number.out","w",stdout); 
        int n;
        scanf("%d",&n);
        int X,Y,sx,sy,ans=0;
        bool ok;
        for(int x=1;x<n;x++)
        {
            X=x; 
            while(X) 
            {
                if(!visx[X%10]) visx[X%10]=true;
                X/=10;
            }
            for(int y=x+1;y<=n;y++)
            {
                Y=y; 
                while(Y) 
                {
                    if(!visy[Y%10]) visy[Y%10]=true;
                    Y/=10;
                }
                ok=true;
                for(int i=0;i<10 && ok;i++)
                    if(visx[i]!=visy[i]) ok=false;
                ans+=ok;
                memset(visy,0,sizeof(visy));
            }
            memset(visx,0,sizeof(visx));
        }
        printf("%d",ans);
    }
    View Code

    贪心

    肯定是上升的时候,越大越好

    下降的时候,越小越好

    所以有了初步思路:

    每次找连续下降的最后一个,然后找连续上升的最后一个,循环往复

     看似很正确

    但请看下图:

    假设k=2,如果按上面的思路,那么后面会选上9

    接下来要找连续下降 9后面那个点和8都不满足k=2的差值

    所以我们得到的答案=4

    但最优解是不要9,选后面的12和8

    因为9后面的那个点不能下降,所以到了12仍然是处于上升,所以12比9更优

    所以,我们不能找连续的序列,而是

    只要现在处于上升阶段,就找最大的

    只要现在处于下降阶段,就找最小的

    幸亏打了暴力,对拍拍出了这个bug

    #include<algorithm>
    #include<cstdio>
    #include<iostream>
    
    #define N 1000001
    
    using namespace std;
    
    int e[N];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    int main()
    {
        freopen("wave.in","r",stdin);    
        freopen("wave.out","w",stdout);
        int n,k;
        read(n); read(k);
        for(int i=1;i<=n;i++) read(e[i]);
        bool up=true;
        int now,len=1;
        for(now=1;now<=n && e[now+1]<=e[now];now++);
        int last=e[now++]; 
        while(now<=n)
        {
            if(!up)
            {
                while(now<=n)
                {
                    if(last-e[now]>=k) { last=e[now]; len++; up^=1; break; }
                    else if(e[now]>=last ) last=e[now];
                    now++;
                }
            }
            else
            {
                while(now<=n)
                {
                    if(e[now]-last>=k) { last=e[now]; len++; up^=1; break; }
                    else if(e[now]<=last) last=e[now];
                    now++;
                }
            }
            now++;
        }
        printf("%d",len);
    }
    View Code

    对拍代码(n^2)

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    #define N 1000001
    
    using namespace std;
    
    int f[N][2],a[N];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    int main()
    {
        freopen("data.in","r",stdin);
        freopen("std.out","w",stdout);
        int n,k;
        read(n); read(k);
        for(int i=1;i<=n;++i) read(a[i]);
        int mx,ans=0;
        for(int i=1;i<=n;i++)
        {
            mx=0;
            for(int j=i-1;j;j--) 
                if(a[j]-a[i]>=k) mx=max(mx,f[j][1]);
            f[i][0]=mx+1; ans=max(ans,f[i][0]);
            mx=0;
            for(int j=i-1;j;j--)
                if(a[i]-a[j]>=k) mx=max(mx,f[j][0]);
            if(mx)
            {
                f[i][1]=mx+1; 
                ans=max(ans,f[i][1]);
            }
        }
        printf("%d",ans);
    }
    View Code
  • 相关阅读:
    Photosynth Deep Zoom 3D 应用演示效果~~酷!
    Python自由之路(四)变量作用域
    Python自由之路(二)Unittest Framework
    经典绚丽的JS特效收藏
    Helloworld Structs2 注意事项
    Blend 3.0 入门之数据绑定(How to Create SampleData)
    Python自由之路(三) 多线程处理
    Nutch 1.0 完全配置笔记
    Probems for Hosted ADO.NET Data Services & Silverlight
    如何开发你的第一个Java Google App Engine 程序
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7681480.html
Copyright © 2011-2022 走看看