• 5月25日


    5月25日

    CF1430F Realistic Gameplay

    山风好评,真凉快。合唱队的衣服好评,zyn小西装真好看。贪心题。

    首先对于某一波怪物,要不换一次弹,打满 ([l,r]),要么不换弹随便打 ((r-l) imes k<a[i]) ,要么介于两个中间

    先想的是dp[i]表示当前还剩i颗子弹,然后每次要不连着打要不新浪费一次弹。

    后来想到不用那么多状态,只要记dp[i]表示最后一次浪费在哪个前面,应该也能过了,详见 Thaumaturge

    然后想到可以贪心,如果下面连着的一段怪物不需要换弹,那么一定不换更优(因为要换了后面还有空隙可以换),所以就可以先算出某一段开头处(不一定是一个),所需最小起始子弹就可以不换弹,这个从后往前推一下就好了,尽量放在后面打,因为如果 (r_{i-1}==l_i) 的地方可以留给上一段用,每次不仅考虑自己,还要考虑 (r_i) 处要留多少给下一波。然后从前往后贪一遍什么时候换弹,一定换才换。

    #include <bits/stdc++.h>
    typedef long long ll;
    const int N=2005;
    int n,k,l[N],r[N],a[N];
    ll ans,dp[N];
    int main(){
    	scanf("%d%d",&n,&k);
    	for (int i=1;i<=n;i++)
    		scanf("%d%d%d",&l[i],&r[i],&a[i]),ans+=a[i];
    	for (int i=n;i>=1;i--){
    		dp[i]=(r[i]==l[i+1]?dp[i+1]:0);
    		if ((ll)(r[i]-l[i]+1)*k<a[i]+dp[i])
    			return puts("-1"),0;
    		dp[i]=dp[i]+a[i]-(ll)(r[i]-l[i])*k;
    		if (dp[i]<0) dp[i]=0;
    	}
    	ll res=0;
    	for (int i=1;i<=n;i++){
    		if (res<dp[i]){
    			ans+=res;
    			res=k;
    		}
    		res=(res-a[i])%k;
    		res=(res+k)%k;
    	}
    	printf("%lld
    ",ans);
    } 
    

    CF1425I Impressive Harvesting of The Orchard

    根号分治+吉老师线段树

    有点困,看了一眼题解是根号分治以为按子树大小分治,想了半天想不出发现是按 (a_i) 分治。

    对于大于根号的,直接dfs记录父亲节点被采集的时间点,每次 (+a_i) 二分到下一次被采集,算答案。

    对于小于根号的,枚举一下不同的 (a_i) ,分别建一棵线段树。对于每一次询问,只对 (le T) 的有关系,答案即为 (le T) 的个数和深度和,然后再讲所有 (le T) 的数赋值为 (T+a_i)。听说这个东西可以用吉老师线段树做,这个东西可以参考吉老师的课件

    突然去看了一眼记录,看起来写nq比较靠谱,不想写了怎么办啊。算了算了还是先不写了

    SOJ1281 简

    相同长度的链一样,链长共6中,记搜+容斥

    soj1282 单

    3*n网格图最短路求和,分治+dp+二维数点

    CF1251D Nastia Plays with a Tree

    又到了 水题量的夜晚时刻了!

    首先肯定找一个度数为1的点当链顶,然后,度数>2的是肯定要断掉某些边的,感觉是只要优先断两边度数都>2的,然后挑一个子树的叶子节点连到某一个叶子就好了,不知道对不对,我去看题解了。

    感觉题解不太符合我的想法(什么鬼话)?还是自己写一发好了,发现连边不用再删边时处理,最后随便首尾相连就好了

    冲题量失败了,有点问题,完善一下,像树形dp一样先把下面做完,如果有两条链就并起来,断掉x和fa的边,而那些多于两条边的也要断掉。

    #include <bits/stdc++.h>
    const int N=200005;
    int n,d[N],last[N],Next[N<<1],to[N<<1],edge,f[N],use[N],ans;
    int son1[N],son2[N];
    int T,x,y;
    struct Edge{
    	int x,y;
    }a[N]; 
    void clear(){
    	for (int i=1;i<=n;i++) d[i]=0,last[i]=0,son1[i]=son2[i]=0;
    	edge=0;
    }
    void add(int x,int y){
    	to[++edge]=y;
    	Next[edge]=last[x];
    	last[x]=edge;
    }
    void dfs(int x,int y){//x/y表示和父亲有没有边 
    	f[x]=y;
    	int tg1=0,tg2=0;
    	for (int i=last[x];i;i=Next[i]){
    		int u=to[i];
    		if (u==y) continue;
    		dfs(u,x);
    		if (!use[u]) continue;
    		if (!tg1) tg1=u;
    		else if (!tg2) tg2=u;
    		else{
    			use[u]=0,ans++;
    			son2[u]=u;
    		}
    	}
    	if (tg1 && tg2){
    		son1[x]=son1[tg1];
    		son2[x]=son1[tg2];
    		use[x]=0;
    		if (x!=1) ans++;
    	}else if (tg1) son1[x]=son1[tg1],use[x]=1;
    	else son1[x]=x,use[x]=1;
    }
    int main(){
    	scanf("%d",&T);
    	while (T--){
    		clear();
    		scanf("%d",&n);
    		for (int i=1;i<n;i++){
    			scanf("%d%d",&x,&y);
    			add(x,y),add(y,x);
    			d[x]++,d[y]++; 
    		} 
    		ans=0;
    		dfs(1,0);
    		printf("%d
    ",ans);
    		int lst=son1[1];
    		for (int i=2;i<=n;i++)
    			if (!use[i]){
    				printf("%d %d %d %d
    ",i,f[i],lst,son1[i]);
    				if (!son2[i]) lst=i;
    				else lst=son2[i];
    			}
    		lst=son1[1];
    	
    	}
    }
    
    * 生而自由 爱而无畏 *
  • 相关阅读:
    NOI2015 品酒大会
    BJOI2017 喷式水战改
    代码注释
    mysql zip 安装 和 修改密码
    Jrebel 永久免费激活步骤
    layui 在springboot2.x 时,页面展示不了layui的问题
    最小生成树
    loj 10117 简单题(cqoi 2006)
    vijos 1512 SuperBrother打鼹鼠
    vijos 清点人数
  • 原文地址:https://www.cnblogs.com/flyfeather6/p/14812141.html
Copyright © 2020-2023  润新知