又考了一场试,昨天放假稍蒙比...,距离csps还有十天,希望比以前的自己更用心
A. 陶陶摘苹果
做法有很多,联想起以前考过的一个单调栈、倍增的题,然而我直接用的无脑线段树做法。
倒序建树离线储存答案,每次因为在修改点之前的决策不受影响,所以可以预处理前面的影响
后面的影响其实就是一个单调栈嘛.......
%%%%%%zzn,xkl用分块在线跑过
B. 开心的金明
一道很大神的贪心题。。。。。。
题面是在考我的语文阅读能力QAQ
首先对于原材料而言,他的成本对每个月而言都是可以提前算出来的
然后对于电脑而言一个时有储存的限制,一个是有生产的限制
考场上打的是$n*e_{i}$的DP,但是$e$的范围是$1e8$,当场去世,想写贪心却没有思路
首先需要知道一个性质,对于当前销售,销售成本更低的商品提前销售更优,
因为在不考虑储存限制的情况小,当前商品$->$下一个月都是加了一个$E_{i}$的值,也就是说他们的优先程度还是不变的
当我们现在选择最优的一定不会是结果更差。
然后我们每次都将全部生产,在以后的转移中如果发现可储存的值比较小,就舍弃掉成本最大的计算机,可以用一个堆来实现
至于$WA80$(也可能$WA10$)是因为可能存在当前的计算机总数小于当前的$e_{i}$数量
注意细节
1 #include<bits/stdc++.h> 2 #define MAXN 2100000 3 #define inf 0x7ffffffffffff 4 #define int long long 5 using namespace std; 6 int read(){ 7 char c=getchar();int x=0;int ff=1; 8 while(c<‘0‘||c>‘9‘){if(c==‘-‘)ff=-1;c=getchar();} 9 while(c>=‘0‘&&c<=‘9‘){x=(x<<1)+(x<<3)+(c^48);c=getchar();} 10 return x*ff; 11 } 12 int c[MAXN];//原材料费用 13 int d[MAXN];//需求 14 int p[MAXN];//生产量 15 int m[MAXN];//电脑价钱 16 int e[MAXN];//电脑储存数 17 int R[MAXN];//原材料储存价钱 18 int E[MAXN];//电脑储存价钱 19 int n; 20 int noww[MAXN];int ok; 21 struct node{ 22 int val,sum,id; 23 friend bool operator <(node a,node b){ 24 return a.val>b.val; 25 } 26 }kx[MAXN]; 27 priority_queue<node>q; 28 bool cmp(node a,node b){ 29 return a.val>b.val; 30 } 31 int sum[MAXN]; 32 int ans=0; 33 signed main(){ 34 freopen("happy.in","r",stdin); 35 freopen("happy.out","w",stdout); 36 n=read(); 37 for(int i=1;i<=n;++i){ 38 c[i]=read();d[i]=read();m[i]=read();p[i]=read(); 39 } 40 for(int i=1;i<=n-1;++i){ 41 e[i]=read();R[i]=read();E[i]=read(); 42 } 43 noww[1]=c[1]; 44 for(int i=2;i<=n;++i){ 45 noww[i]=min(noww[i-1]+R[i-1],c[i]); 46 } 47 for(int i=1;i<=n;++i){ 48 q.push((node){noww[i]+m[i],p[i],i}); 49 sum[i]=p[i]; 50 ans+=(noww[i]+m[i])*p[i]; 51 int ned=d[i];int tot=0;int tsum=0; 52 while(!q.empty()){ 53 node x=q.top();q.pop(); 54 if(ned>=x.sum){ 55 ned-=x.sum; 56 sum[x.id]-=x.sum; 57 } 58 else{ 59 sum[x.id]-=ned;ned=0; 60 } 61 if(sum[x.id]!=0){ 62 kx[++tot].id=x.id; 63 kx[tot].sum=sum[x.id]; 64 kx[tot].val=x.val; 65 tsum+=sum[x.id]; 66 } 67 } 68 if(ned!=0){ok=1;break;} 69 sort(kx+1,kx+tot+1,cmp); 70 for(int j=1;j<=tot;++j){ 71 if(tsum<=e[i])break; 72 if(tsum-e[i]>=sum[kx[j].id]){ 73 ans-=kx[j].val*sum[kx[j].id]; 74 tsum-=sum[kx[j].id]; 75 sum[kx[j].id]=0; 76 } 77 else { 78 ans-=kx[j].val*(tsum-e[i]); 79 sum[kx[j].id]-=tsum-e[i]; 80 tsum=e[i]; 81 } 82 } 83 for(int j=1;j<=tot;++j){ 84 if(sum[kx[j].id]==0)continue; 85 q.push((node){kx[j].val+E[i],sum[kx[j].id],kx[j].id}); 86 } 87 ans+=tsum*E[i]; 88 } 89 if(ok==1)printf("-1"); 90 else printf("%lld\n",ans); 91 }
思路积累:
1.贪心思考,可以先加后来根据决策再减,类似反悔的过程
2.别死刚DP....
C. 笨小猴
由于某些sb理由考场随机化没有AC,注意结构体的下标与原下标的关系
然后可以瞎rand了....