• 2016"百度之星"


    题目链接:

      http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=701

    1001 :

     矩阵快速幂

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include<queue>
    #include<vector>
    using namespace std;
    const int N = 5e5+20, M = 1e2+10, mod = 1000000007,inf = 1e9;
    typedef long long ll;
    struct Matix {
        ll arr[M][M];
    };
    ll x,m,k,c;
    Matix mul(Matix a,Matix b,ll hang ,ll lie) {
        Matix ans;
        memset(ans.arr,0,sizeof(ans.arr));
        for(int i=1;i<=hang;i++) {
          for(int t=1;t<=lie;t++)
            for(int j=1;j<=lie;j++) {
             ans.arr[i][t]+=(a.arr[i][j]*b.arr[j][t]);
             ans.arr[i][t]%=k;
            }
        }
        return ans;
    }
    Matix pow(Matix ans,Matix a,ll x) {
        while(x) {
            if(x&1) ans=mul(ans,a,2,2);
            a=mul(a,a,2,2);
            x/=2;
        }
        return ans;
    }
    int main(){
        ll x,y,z;
        int T,cas=1;
        scanf("%d",&T);
        while(T--) {
            scanf("%I64d%I64d%I64d%I64d",&x,&m,&k,&c);
            Matix fir,sec;
            Matix now;
            now.arr[1][1]=x;
            now.arr[1][2]=x;
            memset(fir.arr,0,sizeof(fir.arr));
            sec.arr[1][1]=10;sec.arr[1][2]=0;
            sec.arr[2][1]=1;sec.arr[2][2]=1;
            fir.arr[1][1]=1;
            fir.arr[2][2]=1;
            fir=pow(fir,sec,m-1);fir=mul(now,fir,2,2);
            printf("Case #%d:
    ",cas++);
            if(fir.arr[1][1]==c)puts("Yes");
            else puts("No");
        }
        return 0;
    }
    View Code

    1002:

     状态压缩DP

      我们设定dp[1<<16][16]:dp[i][j]:i为当前选取的状态并以第j个数结尾的最大值,那么答案就是 max{dp[全集][k]} k属于0到n-1

      对于dp[i][j] , i这个状态已经填了x个数,我们准备填第x+1个数时, 如果当前x+1位置必填某个数,那么 就只更新以规定的这个数结尾转移方程

      如果没有那就 枚举那么可以任意放的数来更新相应的状态及答案

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include<queue>
    #include<vector>
    using namespace std;
    const int N = 1<<17, M = 1e6+10, mod = 1000000007,inf = 1e9;
    typedef long long ll;
    
    ll dp[1<<17][17];
    int n,a[N],p[N],H[N],F[N];
    int main() {
        int T,cas = 1;
        scanf("%d",&T);
        while(T--) {
            scanf("%d",&n);
            memset(H,0,sizeof(H));
            memset(F,-1,sizeof(F));
            int tmp = 0;
            for(int i=0;i<n;i++) {
                scanf("%d%d",&a[i],&p[i]);
                if(p[i]!=-1)
                 H[i] = 1,F[p[i]] = i;
            }
            for(int i=0;i<(1<<n);i++)
                for(int j=0;j<n;j++) dp[i][j] = -1e18;
      //      for(int i=0;i<n;i++)
        //        for(int j=0;j<n;j++) if(i!=j&&!H[i]&&!H[j]) dp[(1<<i)|(1<<j)][j] = a[i]*a[j], dp[(1<<i)|(1<<j)][i] = a[i]*a[j];
           if(F[0]!=-1) dp[(1<<F[0])][F[0]] = 0;
           else {
            for(int i=0;i<n;i++) {
                if(!H[i]) dp[(1<<i)][i] = 0;
            }
           }
           int U = (1<<n) - 1;
            for(int i=1;i<=U;i++) {
                int counts = 0;
                for(int j=0;j<n;j++) if((1<<j)&(i)) counts++;
                if(F[counts]!=-1) {
                    counts = F[counts];
                    for(int j=0;j<n;j++) if(i&(1<<j)&&counts!=j)dp[i|(1<<(counts))][counts] = max(dp[i][j]+a[j]*a[counts],dp[i|(1<<counts)][counts]);
                }
                else {
                    for(int k=0;k<n;k++) {
                        if((1<<k)&(i))
                        for(int j=0;j<n;j++) {
                           if(!((1<<j)&i)) {
                                dp[i|(1<<j)][j] = max(dp[i|(1<<j)][j],dp[i][k]+a[k]*a[j]);
                            }
                        }
                    }
                }
            }
            printf("Case #%d:
    ",cas++);
            ll ans = -1e18;
            for(int i=0;i<n;i++) ans = max(dp[U][i],ans) ;
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code

     1004:D Game

      区间dp

      设定dp[i][j]为i到j这个区间的最大答案,每次去选择连续不连续的2个/3个去删除,暴力转移就好

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include<map>
    using namespace std;
    const int N = 315, M = 30005, mod = 1e9 + 7, inf = 0x3f3f3f3f;
    typedef long long ll;
    
    int dp[N][N];
    ll a[N],d;
    map<ll,int > mp;
    int dfs(int l,int r) {
        if(dp[l][r]!=-1) return dp[l][r];
        int& ret = dp[l][r];
        ret = 0;
        if(l>=r) return ret;
    
        if(l+1==r) {
            if(mp[a[r]-a[l]]) return (ret = 2);
            else return (ret = 0);
        }
    
        int tmp = 0;
        if(mp[a[r]-a[l]]) tmp+=2;// cout<<a[r]-a[l]<<endl;
        if(dfs(l+1,r-1)==((r-1)-(l+1)+1)) ret = tmp+((r-1)-(l+1)+1);
        if(abs(a[r]-a[l])%2==0&&mp[(a[r]-a[l])/2])
        for(int i=l+1;i<r;i++) {
            tmp = 0;
            if(a[r]-a[i]==a[i]-a[l]&&mp[a[i]-a[l]]) {
                tmp = 3;
            }
            else continue;
            if(tmp+dfs(l+1,i-1)+dfs(i+1,r-1)==r-l+1) {
                ret = r-l+1;break;
            }
        }
    
        for(int i=l+1;i<r;i++) {
            ret = max(ret,dfs(l,i)+dfs(i+1,r));
        }
        return ret;
    }
    int main() {
        int T,m,n;
        scanf("%d",&T);
        while(T--) {
            mp.clear();
            memset(dp,-1,sizeof(dp));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
            for(int i=1;i<=m;i++) scanf("%I64d",&d),mp[d] = 1;
            printf("%d
    ",dfs(1,n));
        }
        return 0;
    }
    
    /*
    1
    7 2
    1 5 8 101 59 62 201
    100 3
    */
    View Code

    1005:

     预处理+dfs

     预处理每种长度,每种长度的答案

     再对对应长度dfs求出答案

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include<queue>
    #include<vector>
    using namespace std;
    const int N = 1e3+20, M = 1e6+10, mod = 1000000007,inf = 1e9;
    typedef long long ll;
    
    ll len[N],dp[N],L,R;
    ll dfs(ll x){
        if(x<=0) return 0;
        if(x<=2) return x;
        if(x==3) return 2;
        ll ans=0;
        int pos = upper_bound(len+1,len+62,x) - len - 1;
        if(len[pos]==x) return dp[pos];
        if(x-len[pos]==1) return dp[pos]+1;
        ll ret = dp[pos]+1;
        ll shen = x-len[pos]-1;
        return ret+shen - dp[pos] + dfs(len[pos] - shen);
    }
    int main() {
        dp[1] = 1;
        len[1] = 1;
        for(int i=2;i<=61;i++) {
            len[i] = len[i-1]*2+1;
        }
        for(int i=2;i<=61;i++) {
            dp[i] = dp[i-1] + 1 + len[i-1] - dp[i-1];
        }
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%I64d%I64d",&L,&R);
            printf("%I64d
    ",dfs(R)-dfs(L-1));
        }
        return 0;
    }
    View Code

    1006

     优先队列

     首先按照拓扑,将入度为0的压入,优先位置大的放前面。。。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include<queue>
    #include<vector>
    using namespace std;
    const int N = 5e5+20, M = 1e6+10, mod = 1000000007,inf = 1e9;
    typedef long long ll;
    
    
    int k,c,x,d[N],n,m,vis[N];
    vector<int >G[N]; int ans[N];
    int main() {
        int T;
        int cas = 1;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++) G[i].clear();
            for(int i=1;i<=n;i++) vis[i] = 0,d[i] =  0;
            for(int i=1;i<=m;i++) {
                int a,b;
                scanf("%d%d",&a,&b);
                G[a].push_back(b);
                d[b]++;
            }
            priority_queue<int > q;
            
            for(int i=1;i<=n;i++) {
                if(d[i]==0) q.push(i);
            }
            int cnt =0 ;
            while(!q.empty()) {
                int k  = q.top();
                ans[++cnt] = k;
              //  cout<<k<<endl;
                q.pop();
                for(int i=0;i<G[k].size();i++) {
                    d[G[k][i]]--;
                    if(d[G[k][i]]==0&&!vis[G[k][i]]) {
                        q.push(G[k][i]);
    
                        vis[G[k][i]] = 1;
                    }
                }
            }
            int mi = 1e9;
            ll aa = 0;
            for(int i=1;i<=cnt;i++) {
                mi = min(ans[i],mi);
                aa  = aa + mi;
            }
            printf("%I64d
    ",aa);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    cookie简介
    Javaweb
    apache-tomcat-7.0.92
    学javaweb 先学Servlet 应用理论很重要
    DataGuard切换(主库为Rac+备库为Rac)
    Oracle 迁移 序列
    oracle SQL 执行进度
    ORA-20011 ORA-29913 KUP-11024 GATHER_TABLE_STATS
    盘点 Oracle 11g 中新特性带来的10大性能影响
    查询近一个月的表空间使用情况
  • 原文地址:https://www.cnblogs.com/zxhl/p/5515232.html
Copyright © 2020-2023  润新知