zoukankan      html  css  js  c++  java
  • CF 82 D.Two out of Three

    前言

    全网唯一不同题解

    (f[i][j]) 表示第 (i) 次选取留下来的数是 (k) 的最小花费

    枚举前面的留下来的点 (k) 当前能留下的点只有 ((2*i),(2*i+1),k) 中的一个,时间复杂度 (O(n^2))

    选取次数是 (n/2) 向上取整。因为最后什么点也不留下,(a[n+1]=0),所以答案可以为 (f[m][n+1](m=n/2向上取整))

    另外我没有写记录路径,记录一下也挺简单

    Code

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define INF 0x3f3f3f3f
    using namespace std;
    inline int read() {
    	int x=0,f=1; char ch=getchar();
    	while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    	while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    	return x * f;
    }
    const int N = 1007;
    int n;
    int a[N];
    int f[N][N];
    inline int Const(int x,int y) {
    	return max(a[x], a[y]);
    }
    int main()
    {
    	n = read();
    	for(int i=1;i<=n;++i)
    		a[i] = read();
    	memset(f, 0x3f, sizeof(f));
    	f[1][1] = max(a[2],a[3]); f[1][2] = max(a[1],a[3]); f[1][3] = max(a[1],a[2]);
    	int m = n&1 ? n/2+1 : n/2;
    	for(int i=2;i<=m;++i) {
    		int x = 2*i, y = 2*i+1;	// i次选取的最后两个数 
    		for(int k=1;k<x;++k) {	//枚举上一次留下的数 
    			f[i][x] = min(f[i][x], f[i-1][k]+Const(y,k));
    			f[i][y] = min(f[i][y], f[i-1][k]+Const(x,k));
    			f[i][k] = min(f[i][k], f[i-1][k]+Const(x,y));
    		}
    	}
    	int ans = f[m][n+1];
    	printf("%d
    ",ans);
    	return 0;
    }
    

    update

    加上路径记录版

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define INF 0x3f3f3f3f
    using namespace std;
    inline int read() {
    	int x=0,f=1; char ch=getchar();
    	while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    	while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    	return x * f;
    }
    const int N = 1007;
    int n;
    int a[N];
    int f[N][N];
    struct operation {
    	int x,y,pre;
    }p[N][N];
    inline int Const(int x,int y) {
    	return max(a[x], a[y]);
    }
    void output(int now,int pos) {
    	if(now == 0) return ;
    	output(now-1,p[now][pos].pre);
    	if(a[p[now][pos].x])	
    		printf("%d ",p[now][pos].x);
    	if(a[p[now][pos].y])
    		printf("%d",p[now][pos].y);
    	puts("");
    }
    int main()
    {
    	n = read();
    	for(int i=1;i<=n;++i)
    		a[i] = read();
    	memset(f, 0x3f, sizeof(f));
    	f[1][1] = max(a[2],a[3]); f[1][2] = max(a[1],a[3]); f[1][3] = max(a[1],a[2]);
    	p[1][1] = (operation)<%2,3,0%>;
    	p[1][2] = (operation)<%1,3,0%>;
    	p[1][3] = (operation)<%1,2,0%>;
    	int m = n&1 ? n/2+1 : n/2;
    	for(int i=2;i<=m;++i) {
    		int x = 2*i, y = 2*i+1;	// i次选取的最后两个数 
    		for(int k=1;k<x;++k) {	//枚举上一次留下的数 
    			if(f[i-1][k]+Const(y,k) < f[i][x]) {
    				f[i][x] = f[i-1][k]+Const(y,k);
    				p[i][x] = (operation)<%k,y,k%>;
    			}
    			if(f[i-1][k]+Const(x,k) < f[i][y]) {
    				f[i][y] = f[i-1][k]+Const(x,k);
    				p[i][y] = (operation)<%k,x,k%>;
    			}
    			if(f[i-1][k]+Const(x,y) < f[i][k]) {
    				f[i][k] = f[i-1][k]+Const(x,y);
    				p[i][k] = (operation)<%x,y,k%>;
    			}
    			// f[i][x] = min(f[i][x], f[i-1][k]+Const(y,k));
    			// f[i][y] = min(f[i][y], f[i-1][k]+Const(x,k));
    			// f[i][k] = min(f[i][k], f[i-1][k]+Const(x,y));
    		}
    	}
    	int ans = f[m][n+1];
    	printf("%d
    ",ans);
    	output(m,n+1);
    	return 0;
    }
    
  • 相关阅读:
    IE10、IE11下SCRIPT5009: “__doPostBack”未定义
    CSS Hack大全-可区分出IE6-IE10、FireFox、Chrome、Opera
    HTML head 头标签
    html5匹配不同分辨率样式
    html5关键帧动画,一个小例子快速理解关键帧动画
    导入Excel到数据库
    JavaScript树(一) 简介
    深入解析浏览器的幕后工作原理(五) 呈现树
    深入解析浏览器的幕后工作原理(四) DOM树
    深入解析浏览器的幕后工作原理(三) 呈现树和 DOM 树的关系
  • 原文地址:https://www.cnblogs.com/BaseAI/p/11757562.html
Copyright © 2011-2022 走看看