zoukankan      html  css  js  c++  java
  • 10.22 比赛总结 修剪草坪(mowlawn)、玉米迷宫(cornmaze)

    地址:http://pan.baidu.com/s/1hq03BIO

    T1:之前想错了= =  f[i]表示前i位,且第i位不选的最小价值   f[i]=min{f[j]+A[i]} ,那么ans=TOT-f[i] n-k<i<n

          正着想f[i]=max{f[j-1]+sum[i]-sum[j],f[i-1]}也可以用单调队列维护

    #include<set>
    #include<map>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N = 100010;
    typedef long long lld;
    #define inf 2147483647777777
    #define For(i,n) for(int i=1;i<=n;i++)
    #define Rep(i,l,r) for(int i=l;i<=r;i++)
    using namespace std;
    
    void read(int &v){
        char ch=getchar();int num=0;
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') {
            num=num*10+ch-'0';
            ch=getchar();
        }
        v=num;
    }
    
    int n,k,l,r;
    lld TOT,ans=inf,f[N];
    int A[N];
    struct queues{
        int id;lld v;
    }q[N];
    
    void init(){
        read(n);read(k);
        For(i,n) read(A[i]),TOT+=A[i];
    }
    
    void dp(){
        For(i,n){
            f[i]=A[i]+q[l].v;
            while(q[r].v>f[i]&&l<=r) r--;
            q[++r].v=f[i];q[r].id=i;
            while(q[l].id<i-k) l++;
        }
        Rep(i,n-k,n) ans=min(ans,f[i]);
        printf("%I64d",TOT-ans);
    }
    
    int main(){
        freopen("mowlawn.in","r",stdin);
        freopen("mowlawn.out","w",stdout);
        init();
        dp();
        return 0;
    }
    T1

     堆版本的,应老师要求写的= =

    #include<set>
    #include<map>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N = 100010;
    typedef long long lld;
    typedef pair<lld,int> point;
    #define w first
    #define id second
    #define For(i,n) for(int i=1;i<=n;i++)
    #define Rep(i,l,r) for(int i=l;i<=r;i++)
    
    point H[N];
    lld ans,TOT;
    int L,Loc[N],n,k,A[N];
    lld dp[N];
    
    //下调
    void Down(int No,point H[]){
        int fa=No,son=No*2;
        while(son<=L){
            if(H[son].w>H[son+1].w&&son<L) {
                //swap(Loc[H[son].id],Loc[H[son+1].id]);
                son++;
            }
            if(H[son].w<H[fa].w) {
                swap(Loc[H[son].id],Loc[H[fa].id]);
                point c=H[son];H[son]=H[fa];H[fa]=c;
            }
            fa=son;son=fa*2;
        }
    }
    //删除堆元素
    void Delete(int No,point H[]){
        Loc[H[L].id]=Loc[H[No].id];
        H[No]=H[L--];
        Down(No,H);
    }
    
    //上调 
    void Up(int No,point H[]){
        int fa=L/2,son=L;
        while(H[son].w<H[fa].w&&son>1){
            swap(Loc[H[son].id],Loc[H[fa].id]);
            point c=H[son];H[son]=H[fa];H[fa]=c;
            son=fa;fa=son/2;
        }
    }
    
    void Insert(point NODE,point H[]){
        H[++L]=NODE;
        Loc[NODE.id]=L;
        Up(L,H);
    }
    
    void init(){
        scanf("%d%d",&n,&k);
        For(i,n) scanf("%d",&A[i]),TOT+=A[i];
    }
    
    void DP(){
        ans=1e18;
        Insert(make_pair(0,0),H);
        For(i,n){
            dp[i]=H[1].w+A[i];
            Insert(make_pair(dp[i],i),H);
            if(i>k)  Delete(Loc[i-k-1],H);
        }
        For(i,n) cout<<dp[i]<<endl;
        Rep(i,n-k,n) ans=(dp[i]<ans)?(dp[i]):(ans);
        printf("%I64d
    ",TOT-ans);
    }
    
    int main(){
        freopen("mowlawn.in","r",stdin);
        freopen("mowlawn.out","w",stdout);
        init();
        DP();
        return 0;
    }
    

    T2: 很坑爹的bfs,考场上没看到是一些传送门。。就写了一个传送门的。。。由于增量是1,所以可以不用bfs

     1 #include<set>
     2 #include<map>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<iostream>
     7 #include<algorithm>
     8 using namespace std;
     9 const int N = 310;
    10 const int dx[5]={0,-1,1,0,0},
    11           dy[5]={0,0,0,-1,1};
    12 typedef pair<pair<int,int>,int>  newp;
    13 #define x first
    14 #define y second
    15 #define For(i,n) for(int i=1;i<=n;i++)
    16 #define Rep(i,l,r) for(int i=l;i<=r;i++)
    17 char maze[N][N];
    18 int x,y,n,m;bool hash[N][N];
    19 newp q[N*3*N];
    20 pair<int,int> two[3],cnt[30][2];
    21 
    22 void init(){
    23     scanf("%d%d",&n,&m);
    24     For(i,n) {
    25         scanf("%s",maze[i]+1);
    26         For(j,m){
    27             if(maze[i][j]=='@'){x=i;y=j;}
    28             if(isupper(maze[i][j])) 
    29                 if(cnt[maze[i][j]-'A'+1][0].first>0)   cnt[maze[i][j]-'A'+1][1]=make_pair(i,j);
    30                 else                                   cnt[maze[i][j]-'A'+1][0]=make_pair(i,j);
    31         }
    32     }
    33 }
    34 
    35 int BFS(){
    36     int l=0,r=1;q[r]=make_pair(make_pair(x,y),0);hash[x][y]=true;
    37     while(l<r){
    38         newp head=q[++l];
    39         pair<int,int> First=head.x;int w=head.y;
    40         if(maze[First.x][First.y]=='=') return w;
    41         For(i,4){
    42             int tx=First.x+dx[i],ty=First.y+dy[i];
    43             if(tx>n||ty>m||tx<=0||ty<=0) continue;
    44             if(!hash[tx][ty]&&maze[tx][ty]!='#'){
    45                 hash[tx][ty]=true;
    46                 if(isupper(maze[tx][ty])){
    47                       if(cnt[maze[tx][ty]-'A'+1][0]!=make_pair(tx,ty)){
    48                           q[++r]=make_pair(cnt[maze[tx][ty]-'A'+1][0],w+1);
    49                           hash[tx][ty]=false;
    50                       }
    51                       else{
    52                           q[++r]=make_pair(cnt[maze[tx][ty]-'A'+1][1],w+1);
    53                           hash[tx][ty]=false;
    54                       }
    55                     continue;
    56                 }
    57                 q[++r]=make_pair(make_pair(tx,ty),w+1);
    58             }
    59         }
    60     }
    61 }
    62 
    63 int main(){
    64     freopen("cornmaze.in","r",stdin);
    65     freopen("cornmaze.out","w",stdout);
    66     init();
    67     printf("%d
    ",BFS());
    68     return 0;
    69 }
    T2
  • 相关阅读:
    剑指Offer-30.连续子数组的最大和(C++/Java)
    剑指Offer-29.最小的K个数(C++/Java)
    UVA 1616 Caravan Robbers 商队抢劫者(二分)
    UVA 10570 Meeting with Aliens 外星人聚会
    UVA 11093 Just Finish it up 环形跑道 (贪心)
    UVA 12673 Erratic Expansion 奇怪的气球膨胀 (递推)
    UVA 10954 Add All 全部相加 (Huffman编码)
    UVA 714 Copying Books 抄书 (二分)
    UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
    codeforecs Gym 100286B Blind Walk
  • 原文地址:https://www.cnblogs.com/zjdx1998/p/4044328.html
Copyright © 2011-2022 走看看