zoukankan      html  css  js  c++  java
  • 2016-11-13试题解题报告

    2016-11-13试题解题报告

    By shenben

    本解题报告解析均为100分解题思路。

    T1

    贪心

    对于每个数i,把他的不同的左边与右边统计下来。

    那么,对于每个数i的记录的元素b[i]都改b[i]的中位数一定是最优的。

    那么我们统计初始代价,sum/2;

            统计ans=max(b[i]可以减小的代价)

    答案:sum/2-ans

    T2

    区间dp 

    f[i][j](i!=j)表示任意位置(i,j)是'(',')'的概率

    Dp[i][j]表示两边是(i,j)是'(',')',并且中间是合法序列的概率

    dp[i][j]表示区间[i,j]是合法序列的概率

    初始化:if(i+1>j-1) dp[i][j]=Dp[i][j]=f[i][j];
                   else dp[i][j]=Dp[i][j]=dp[i+1][j-1]*f[i][j];

    状态转移:dp[i][j]+=Dp[i][k]*dp[k+1][j];

    T3

    最短路+乘法原理

    对于除1外的所有点,处理出cnt[x],表示1->x的最短路的路径条数

    ans=(i:2->n)∏cnt[i]

    T1代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<ctime>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #define R register
    #define ll long long
    #ifdef unix
    #define LL "%lld"
    #else
    #define LL "%I64d"
    #endif
    #define debug(x) cout<<x<<"----"<<endl
    using namespace std;
    inline int read(){
        R int x=0;bool f=1;
        R char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=0;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    inline char in(){
        for(R char ch=getchar();;ch=getchar()) if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return ch;
    }
    const int N=1e5+10;
    int n,m,a[N];
    vector<int>b[N];
    #define name "note"
    int main(){
        freopen(name".in","r",stdin);
        freopen(name".out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=m;i++) a[i]=read();
        for(int i=2;i<=m;i++) if(a[i-1]!=a[i]) b[a[i-1]].push_back(a[i]);
        for(int i=1;i<m;i++) if(a[i+1]!=a[i]) b[a[i+1]].push_back(a[i]);
        ll ans=0,sum=0;
        for(int i=1,s;i<=n;i++){
            if(!b[i].size()) continue;
            sort(b[i].begin(),b[i].end());
            ll before=0,after=0;
            ll y=b[i][b[i].size()>>1];
            for(int j=0;j<b[i].size();j++){
                before+=(ll)abs(i-b[i][j]);
                after+=(ll)abs(y-b[i][j]);
            }
            ans=max(ans,before-after);
            sum+=before;
        }
        printf(LL,sum/2-ans);
        fclose(stdin);
        fclose(stdout);
        return 0;
    } 
    /*25分存档 
    const int N=1e5+10;
    const int inf=0x7fffffff;
    int n,m,cnf,a[N],b[N];
    struct node{
        int v,x;
    }f[N],bf[N];
    int zmx,p,ans;
    int pos[110];
    bool vis[110];
    inline int ABS(int x){
        return x>0?x:-x;
    }
    void go(){
        int maxx=0,minx=inf;ans=inf;
        for(int i=1;i<=m;i++) maxx=max(maxx,a[i]),minx=min(minx,a[i]),vis[a[i]]=1;
        for(int i=minx;i<=maxx;i++){
            if(!vis[i]) continue;
            memcpy(b,a,sizeof a);
            pos[0]=0;
            for(int j=1;j<=m;j++){
                if(b[j]==i) pos[++pos[0]]=j;
            }
            for(int k=minx;k<=maxx;k++){
                if(k==i) continue;
                int tmp=0;
                for(int l=1;l<=pos[0];l++) b[pos[l]]=k;
                for(int l=1;l<m;l++) tmp+=ABS(b[l+1]-b[l]);    
                ans=min(ans,tmp);
            }
        }
        printf("%d",ans);
    }
    #define name "note"
    int main(){
        freopen(name".in","r",stdin);
        freopen(name".out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=m;i++) a[i]=read();
        if(n<=100&&m<=100){go();return 0;}
        f[cnf=1].v=a[1];f[1].x=1;
        for(int i=2;i<=m;i++){
            if(a[i]==f[cnf].v) f[cnf].x++;
            else{
                f[++cnf].v=a[i];f[cnf].x=1;
            }
        }
        for(int i=1;i<=cnf;i+=2) if(f[i].v==f[i+2].v){
            if(f[i].x+f[i+2].x>zmx){
                zmx=f[i].x+f[i+2].x;
                p=i;
            }
        }
        for(int i=2;i<=cnf;i+=2) if(f[i].v==f[i+2].v){
            if(f[i].x+f[i+2].x>zmx){
                zmx=f[i].x+f[i+2].x;
                p=i;
            }
        }
        for(int i=1;i<m;i++) ans+=ABS(a[i+1]-a[i]);
        if(p){
            int xg=f[p].v;
            p++;
            int tmp=f[p].v;
            for(int i=1;i<=m;i++) if(f[i].v==tmp) f[i].v=xg;
            int temp=0;
            for(int i=1;i<p;i++) temp+=ABS(f[i+1].v-f[i].v);
            for(int i=p+1;i<m;i++) temp+=ABS(f[i+1].v-f[i].v);
            ans=min(ans,temp);
        }
        for(int i=1,t;i<cnf;i++) if((t=ABS(f[i].v-f[i+1].v))>zmx){
            zmx=t;p=i;
        }
        memcpy(bf,f,sizeof f);
        int tmp1=bf[p].v;
        int tmp2=bf[p+1].v;
        int temp=0;
        for(int i=1;i<=cnf;i++) if(bf[i].v==tmp1) bf[i].v=tmp2;
        for(int i=1;i<cnf;i++) temp+=ABS(bf[i+1].v-bf[i].v);
        ans=min(ans,temp);
        memcpy(bf,f,sizeof f);
        temp=0;
        for(int i=1;i<=cnf;i++) if(bf[i].v==tmp2) bf[i].v=tmp1;
        for(int i=1;i<cnf;i++) temp+=ABS(bf[i+1].v-bf[i].v);
        ans=min(ans,temp);
        printf("%d",ans);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }*/ 

    T2代码:

    #include<cstdio>
    using namespace std;
    const int N=201;
    int n,w;
    double l[N][N],r[N][N];
    double f[N][N],Dp[N][N],dp[N][N];
    #define name "brackets"
    int main(){
        freopen(name".in","r",stdin);
        freopen(name".out","w",stdout);
        scanf("%d%d",&n,&w);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=w;j++){
                scanf("%lf%lf",&l[i][j],&r[i][j]);
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                for(int k=1;k<=w;k++){
                    f[i][j]+=l[i][k]*r[j][k];
                }
            }
        }
        //Dp[][]必须要有,因为他是判重的 
        for(int i=n;i;i--){
            for(int j=i+1;j<=n;j++){
                //( A )
                if(i+1>j-1) dp[i][j]=Dp[i][j]=f[i][j];
                else dp[i][j]=Dp[i][j]=dp[i+1][j-1]*f[i][j];
                //(A)合并(B) 
                for(int k=i+1;k<j;k++) dp[i][j]+=Dp[i][k]*dp[k+1][j];
            }
        }
        printf("%.5lf",dp[1][n]);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    /*
    15分 乱搞代码不存了
    */

    T3代码:

    /*
    检验最短路径条数时,手残的打了个松弛,WA了8个点。长记性了。
    */
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<ctime>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #define R register
    #define ll long long
    #define DB double
    #define pir pair<int,int>
    #ifdef unix
    #define LL "%lld"
    #else
    #define LL "%I64d"
    #endif
    #define debug(x) cout<<x<<"----"<<endl
    using namespace std;
    inline int read(){
        R int x=0;bool f=1;
        R char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=0;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    inline char in(){
        for(R char ch=getchar();;ch=getchar()) if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return ch;
    }
    const int N=1e5+10;
    const int M=1e6+10;
    struct ss{
        int u,v,w;
        bool operator <(const ss &a)const{
            return w<a.w;
        }
    }ed[M];
    struct node{
        int v,w,next;
    }e[M*2];
    int n,m,tot,head[N],dis[N];
    ll ans=1,cnt[N];
    const ll mod=(1LL<<31)-1;
    bool vis[N];
    void add(int x,int y,int z){
        e[++tot].v=y;
        e[tot].w=z;
        e[tot].next=head[x];
        head[x]=tot;
    }
    const int inf=2e9;
    inline void dijkstra(){
        priority_queue<pir,vector<pir>,greater<pir> >q;
        for(int i=1;i<=n;i++) dis[i]=inf;
        dis[1]=0;
        q.push(make_pair(0,1));
        while(!q.empty()){
            pir t=q.top();q.pop();
            int x=t.second;
            if(vis[x]) continue;
            vis[x]=1;
            for(int i=head[x];i;i=e[i].next){
                int v=e[i].v,w=e[i].w;
                if(!vis[v]&&dis[v]>dis[x]+w){
                    dis[v]=dis[x]+w;
                    q.push(make_pair(dis[v],v)); 
                }
            }
        }
    }
    int q[N<<1]={0};
    const int QLEN=N*2-5;
    inline void spfa(){
        memset(vis,0,sizeof vis);
        int h=0,t=1;
        dis[1]=0;
        vis[1]=1;
        q[t]=1;
        while(h<t){
            if(++h>QLEN) h=1;
            int x=q[h];
            //vis[x]=0;//单纯检验最短路,(不更新),不需要松弛 
            for(int i=head[x];i;i=e[i].next){
                int v=e[i].v,w=e[i].w;
                if(dis[v]==dis[x]+w){
                    if(++cnt[v]>=mod) cnt[v]-=mod;
                    if(!vis[v]){
                        vis[v]=1;
                        if(++t>QLEN) t=1;
                        q[t]=v;
                    }
                }
            }
        }
    }
    #define name "castle"
    int main(){
        freopen(name".in","r",stdin);
        freopen(name".out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=m;i++) ed[i].u=read(),ed[i].v=read(),ed[i].w=read();
        sort(ed+1,ed+m+1);
        for(int i=1;i<=m;i++){
            add(ed[i].u,ed[i].v,ed[i].w);
            add(ed[i].v,ed[i].u,ed[i].w);
        }
        dijkstra();
        for(int i=1;i<=n;i++) if(dis[i]==inf){puts("0");return 0;}
        if(n-1==m){puts("1");return 0;}
        spfa();
        for(int i=2;i<=n;i++) ans=(ans*cnt[i])%mod;
        printf(LL,ans);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    Linux权限及归属管理
    Linux账户管理
    随笔记录 磁盘坏道故障 2019.8.7
    随笔记录 MBR扇区故障系统备份与还原 2019.8.7
    随笔记录 grub引导故障修复 2019.8.7
    随笔记录 综合训练 2019.8.5
    随笔记录 磁盘配额2019.8.2
    随笔记录 2019.7.31
    随笔记录 2019.7.31
    随笔记录 linux命令 2019.7.29
  • 原文地址:https://www.cnblogs.com/shenben/p/6058969.html
Copyright © 2011-2022 走看看