zoukankan      html  css  js  c++  java
  • 0920 模拟赛

    T1

    链接

    Idea

    在考场上打了暴力后,发现了一个规律:
    (n)为奇数时,(ans=min{a}-1),当(n)为偶数时,(ans=0)
    但,只有(80pts)ts.png
    我发现(ans=min{a_i-1},i\%2=1)
    所以

    Code

            int n=read();
    	for(int i=1;i<=n;i++) a[i]=read(); 
    	if(n&1){
    		for(int i=1;i<=n;i++)
    			if(i&1)minn=min(minn,a[i]-1);
    		printf("%d",minn);
    	}
    	else puts("0"); 
    

    T2

    链接

    Idea

    考场上没写出来,QAQ,我太菜了lb.png
    现在看来,这是一个很明显的构造题
    在想这道题之前,我们来思考几个问题
    (Q:)把一个序列改成单调不下降的序列,至少需要修改多少个数?
    (A;ans=len-len_{LIS})
    (Q:)把一个序列改成单调递增的序列,至少修要修改几个数?
    (A:)构造序列(b[i]=a[i]-1)(ans=len-len_{LIS_b})
    (Why?) 因为要求严格单调递增,所以前一项与后一项至少相差一,将这个必要的差值减去
    就相当于求(B)改成非严格单增最少需修改的数,也就相当于上一个问题

    现在本题要求把序列改成一个单调递增正整数序列
    那求的就是:首项为非负整数的最长上升子序列

    Code

    int a[maxn],b[maxn],f[maxn],len,n;
    inline int find(int x){
    	int l=1,r=len+1;
    	if(x<f[1]) return 0;
    	while(l+1<r){
    		int mid=l+r>>1;
    		if(f[mid]<=x) l=mid;
    		else r=mid;
    	}
    	return l;
    }
    inline void solve(){
    	len=0;
    	for(int i=1;i<=n;i++){
    		if(b[i]<0) continue;
    		int mid=find(b[i]);
    		len=max(mid+1,len);
    		f[mid+1]=min(f[mid+1],b[i]);
    	}
    	printf("%d
    ",n-len);
    }
    signed main(){
    	int T=read();
    	while(T--){
    		n=read();
    		memset(f,0x3f,sizeof f);
    		for(int i=1;i<=n;i++){
    			a[i]=read();
    			b[i]=a[i]-i;
    		}
    		solve();
    	}
    	return 0;
    }
    

    推荐

    可以写写(CF13C Sequence,POJ3666)

    T3

    链接

    Idea

    这道题是写出来了,但是(MLE)

    这是一道(DP)
    (f[i][x][y][z]) 代表为第i次选择的情况下,对应的1,2,3号服务员
    所对应的位置
    那么可以得知
    (f[i][p[i]][y][z] = min(f[i][p[i]][y][z], f[i - 1][x][y][z] + c[x][p[i]]))
    (f[i][x][p[i]][z] = min(f[i][x][p[i]][z], f[i - 1][x][y][z] + c[y][p[i]]))
    (f[i][x][y][p[i]] = min(f[i][x][y][p[i]], f[i - 1][x][y][z] + c[z][p[i]]))

    因为肯定有一个位置,继承了上一个的位置
    所以保存两个状态就可以了

    三种状态转移 (p_i,x,y)
    (f[i][x][y] = min(f[i][x][y], f[i - 1][x][y] + c[pi - 1][pi]))
    (f[i][pi][y] = min(f[i][pi][y], f[i - 1][x][y] + c[x][pi]))
    (f[i][x][pi] = min(f[i][x][pi], f[i - 1][x][y] + c[y][pi]))

    (sb)的开了(500 imes 500 imes 500)的数组lb.png

    Code

    和上面的状态不同哦
    int T=read(); 
    	while(T--){
    		int n=read(),l=read();
    		memset(f,0x3f,sizeof(f));
    		for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++) 
    			c[i][j]=read();	
    		p[0]=3;
    		for(int i=1;i<=l;i++) p[i]=read();
    		for(int k=1;k<=n;k++) 
    		for(int i=1;i<=n;i++) 
    		for(int j=1;j<=n;j++) 
    		if(c[i][j]>c[i][k]+c[k][j]) 
    			c[i][j]=c[i][k]+c[k][j];	
    		f[0][1][2]=0;
    		for(int i=0;i<=l;i++)
    		for(int j=1;j<=n;j++) 
    		for(int k=1;k<=n;k++){
    			f[i+1][j][k]=min(f[i+1][j][k],f[i][j][k]+c[p[i]][p[i+1]]);
    			f[i+1][p[i]][k]=min(f[i+1][p[i]][k],f[i][j][k]+c[j][p[i+1]]);
    			f[i+1][j][p[i]]=min(f[i+1][j][p[i]],f[i][j][k]+c[k][p[i+1]]);
    		}
    		int ans=inf;
    		for(int i=1;i<=n;i++) 
    		for(int j=1;j<=n;j++){
    			if(i==j) continue;
    			if(f[l][i][j]<ans) ans=f[l][i][j];
    		}
    		printf("%d
    ",ans);
    	}
    

    推荐

    (AcWing 274)

    总结

    开数组一定要开的正好,要计算空间复杂度,考虑要全面.
    惨痛的教训ll.png
    ( ext{相较于丢失你,我更怕的是丢失自我。我想做你眼中站立的影子,不愿摇尾乞怜的拥抱,我愿自爱})

  • 相关阅读:
    php去除字符串(空格,换行,反斜杠)
    周末撸了个Excel框架,现已开源,yyds!!
    Python基础之pytest参数化
    解决 remote: HTTP Basic: Access denied Authentication failed for 'https://'报错
    删除上传 github 中的 .idea 文件夹
    Nacos配置管理最佳实践
    痞子衡嵌入式:在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法
    痞子衡嵌入式:我入选了2021年度与非网(eefocus)星选创作者Top10
    《痞子衡嵌入式半月刊》 第 47 期
    重新iviewUI Modal 组件 ok事件默认直接关闭modal 的行为[Code Snippet]
  • 原文地址:https://www.cnblogs.com/cbyyc/p/11561309.html
Copyright © 2011-2022 走看看