2017年08月08日

https://vjudge.net/contest/50935#problem/J
师兄的代码好看,就照这个模板吧

int stk[N];
int a[N],L[N],R[N];
LL sum[N];
int main(){
    int n;
    while(~sf("%d",&n)){
        sum[0]=0;
        rep(i,1,n){sf("%d",&a[i]),sum[i]=sum[i-1]+a[i];}
        int top=0;
        a[0]=-1;a[n+1]=-1;
        rep(i,0,n+1){
            while(top&&a[i]<=a[stk[top-1]])
                --top,R[stk[top]]=i-1;
            if(top)
                L[i]=stk[top-1]+1;
            stk[top++]=i;
        }
        LL ans=0;int id=0;
        rep(i,1,n){
            if(ans<=(sum[R[i]]-sum[L[i]-1])*a[i]){
                ans=(sum[R[i]]-sum[L[i]-1])*a[i];
                id=i;
            }
        }
        cout<<ans<<endl;
        pf("%d %d\n",L[id],R[id]);
    }
}

https://vjudge.net/contest/50935#problem/K
哇,居然自己过了。。还是模仿师兄的好

int stk[N],a[N],R[N],L[N];
int main(){
    //freopen("in.txt","r",stdin);
    int n;
    while(~sf("%d",&n)){
        int top=0;
        rep(i,1,n){sf("%d",&a[i]); L[i]=i+1;}
        a[n+1]=inf;
        rep(i,1,n+1){
            while(top&&a[i]>=a[stk[top-1]])
                --top,R[stk[top]]=i-1;
            stk[top++]=i;
        }
        LL ans=0;
        rep(i,1,n){
            ans+=(R[i]-L[i]+1);
        }
        cout<<ans<<'\n';
    }
}

https://vjudge.net/contest/50935#problem/L
终于做了一道 单调队列+ dp 的题目了,师兄的代码还是那么好看。。

int n,m;
int dp[120][mxn];
struct node{
    int val,p;
    bool friend operator<(node a,node b){
        return a.val<b.val;
    }
    node(int val,int p):val(val),p(p){};
};
struct worker{
    int l,p,s;
    bool friend operator<(worker a,worker b){
        return a.s<b.s;
    }
}a[150];
int l[N],p[N],s[N];
int main(){
//freopen("in.txt","r",stdin);
    while(~sf("%d%d",&n,&m)){
        mem(dp,0);
        rep(i,1,m){ sf("%d%d%d",&a[i].l,&a[i].p,&a[i].s); }
        sort(a+1,a+1+m);
        rep(i,1,m){ l[i]=a[i].l;p[i]=a[i].p,s[i]=a[i].s; }
        for(int i=1;i<=m;++i){
            priority_queue<node>q;
            for(int k=0;k<s[i];++k){
                q.push(node(dp[i-1][k]-k*p[i],k));
            }
            for(int j=1;j<=n;++j){
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                if(j>=s[i]&&j<s[i]+l[i]){
                    while((j-q.top().p)>l[i]){
                        q.pop();
                    //  if(q.empty())puts("e");
                    }
                    dp[i][j]=max(dp[i][j],j*p[i]+q.top().val);
                }
            }
        }
        pf("%d\n",dp[m][n]);
    }
}

不过这个代码不像是的用单调队列的,,
贴个别人的,用单调队列的。。
https://github.com/zhu8655/OI_Solution/blob/master/POJ_1821.cpp

https://vjudge.net/problem/ZOJ-3699

这个地方师兄用的双端队列很好,思想也很好。
然而找不到为何Segmentation Fault。。。 

int price[N],cost[N];
struct gas{
    int vol,pri;
    gas(int vol,int pri):vol(vol),pri(pri){};
};
int main(){
    int T;sf("%d",&T);
    while(T--){
        int n,cap;sf("%d%d",&n,&cap);
        int flag=0;
        rep(i,1,n){
            int a,b;sf("%d%d%d",&a,&b,&price[i]);
            if(a*b>cap)flag=1;
            cost[i]=a*b;
        }
        if(flag){puts("Impossible");continue;}
        LL ans=0;
        deque<gas>dq;
        int vol=0;
        for(int i=1;i<=n;++i){
            while(!dq.empty()&&price[i]>dq.back().pri){
                vol-=dq.back().vol;
                dq.pop_back();
            }
            dq.push_back(gas(cap-vol,price[i]));
            int need=cost[i];
            while(need){
                gas& cur=dq.front();
                int Min=min(cur.vol,need);
                cur.vol-=Min;
                need-=Min;ans+=1LL*cur.pri*Min;
                if(!cur.vol)dq.pop_front();
            }
        }
        cout<<ans<<'\n';
    }
}

然后有点不懂了,只能再去看别人的代码。。、http://blog.csdn.net/acvay/article/details/46798685这个的代码还挺好的。。

单调队列+ dp

dp[i][j]表示第 i 天,有 j 股的最大收益

状态转移 dp[i][j]=max{dp[i-1]j,dp[r][k]-(j-k)*pa[i](i-r>w,j-k<=na[i],买),dp[r][k]+(k-j)*pb[i](i-r>w,k-j<=nb[i],卖)}

复杂度 为 t*t*p*p

首先我们可以看出 dp[i][j]>=dp[i-1][j](不买不卖转移)

所以可以将 r 确定为 i-w-1,复杂度变为t*p*p 还是很大

然后对于买,移项有

dp[i][j]+j*pa[i]=dp[r][k]+k*pa[i]。右边与 j无关, 可见我们只需要对每一个 i 维护一个关于k的单调队列,就可以在 p时间内求出所有的dp[i][j]

师兄的代码有点不同。。https://vjudge.net/solution/2611950

2:45到4:45
花了快两个小时做一个atcoder 只做了3题。。 结果题目都是看别人的。。。
题解
https://acmle.com/d/70-atcoder-regular-contest-075
醉了,都不会,,只能看
这个
其中E提还是看了这个,而且还有回顾用”树状数组求逆序对“。。。(看来太水了)
http://www.cnblogs.com/yxg123123/p/6938882.html
 PS:数组要从0开始算,不然会少算长度为1的连续子序列。
(debug了很久这个。。。)

晚上就回顾了以前做的题,有些还是不会。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值