luogu 十一 基本套路 day1
P3406 海底高铁
一个重要的推论:
对于一个线段,要不就只买票,要不就用IC卡(贪心嘛)
所以只要比较这两种策略,取较大值就好。
rep(i,1,n-1){
cf[i]+=cf[i-1];
int cnt=cf[i];
rd(a[i]),rd(b[i]),rd(c[i]);
// int cnt=query(i);
if(cnt*b[i]+c[i]<cnt*a[i])
ans+= cnt*b[i]+c[i];
else ans+=cnt*a[i];
}
对线段进行差分:
就不用再右端点+1的位置--,
而是直接再右端点的位置--;
- 原理:线段的个数是端点个数-1
rep(i,1,m-1){
if(p[i]<p[i+1])
cf[p[i]]++,cf[p[i+1]]--;
// add(p[i],1),add(p[i+1],-1);
else if(p[i]>p[i+1])
cf[p[i+1]]++,cf[p[i]]--;
// add(p[i+1],1),add(p[i],-1);
}
【二位前缀和 && 差分】P3397 地毯
rd(n),rd(m);
while(m--){
int x1,y1,x2,y2;
rd(x1),rd(y1),rd(x2),rd(y2);
cf[x1][y1]++,cf[x2+1][y2+1]++;
cf[x1][y2+1]--,cf[x2+1][y1]--;
}
rep(i,1,n)
rep(j,1,n){
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+cf[i][j];
}
P1842 奶牛玩杂技
SOL:
构造相邻的两头牛,看能不能贪心,且看需要满足什么条件的时候才能贪心。
设有相邻的两头牛a,b,来讨论一下在满足什么条件的的情况下a放在b上面比b放在a上面更优:
设放在a,b上面的牛的总重为W
i:a放在b上面
a的压扁值:W-Sa
b的压扁值:W+Wa-Sb
ii:b放在a上面
a的压扁值:W+Wb-Sa
b的压扁值:W-Sb
要使a放在b上面比b放在a上面更优,
则max(W-Sa,W+Wa-Sb,) < max(W+Wb-Sa,W-Sb);
易证W-Sa < W+Wb-Sa,W-Sb<W+Wa-Sb;
那就转化成了使W+Wa-Sb<W+Wb-Sa;
->Wa+Sa < Wb+Sb
综上,当满足这个条件的时候,a放在b上面比b放在a上面更优;
那么我们以Wi+Si为关键字从小到大排序,(此时已经确立各奶牛的位置),那我们从上到下利用前缀和扫一遍最小的压扁值就好啦。
int n,m;
const int N=5e4+10;
struct nainiu{
int s,w;
bool operator < (const nainiu &rhs)const{
return s+w<rhs.s+rhs.w; //贪心
}
}cow[N];
#undef int
int main(){
#define int long long
#ifdef WIN32
freopen("test.txt","r",stdin);
#endif
rd(n);
rep(i,1,n){
rd(cow[i].w),rd(cow[i].s);
}
sort(cow+1,cow+n+1);
int sum=0,ans=INT_MIN;
rep(i,1,n){
ans=max(ans,sum-cow[i].s);
sum+=cow[i].w;
}
printf("%d",ans);
return 0;
}
\(x=\frac{a}{b}\)
P1223 排队接水
*排序不等式:
易知每个同学的等待时间wait[i]是单调递增的
那么总等待时间就是sigma wait[i] * 自己接水的时间t[i],
根据排序不等式,最小的总等待时间应该是逆序和。
好吧上面在胡扯,这只是一个显然的贪心
P1012 拼数
/*
translation:
设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数。
例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213
solution:
sort 排序字符串是不用加cmp的,自带operator (字典序)//sort对字符串排序只能是c++中string类型
按长度排序加一个a.length就可以了 记住cmp里的条件是return小的条件
note:
*字符串排序
date:
2019.07.10
*/
string a[25];
bool cmp(string a,string b)
{
return a+b>b+a;//a+b就是b接在a的后面
}
一些用到了贪心思想的算法
• 哈夫曼编码
• Kruskal求最小生成树
• Dijkstra求单源最短路
P3258 [JLOI2014]松鼠的新家
复习树上点差分
power[u]++,power[v]++;
power[lca(u,v)]--,power[fa[lca(umv)]]--;
debug:
1.打树剖lca的时候return 了深度大的点^^^^^^^^我真是个智娃。
2.不看输出格式,明明1A的……