zoukankan      html  css  js  c++  java
  • 题解[CF82D Two out of Three]

    题意

    Luogu

    CF

    有一列数,每次从前三个中选两个(不足两个则选一个)其中较大者为代价,接着这两个数出列,求让所有数出列的最小代价。

    题解

    状态不好设

    讲的人都这么说

    (i)轮选数后,总共会选(2×i)个数,所以在第(i)轮选数时,是在(前(i-1)轮选数后剩下的那一个数(第(j)个数)和第(i*2)个数,第(i*2+1)个数)这三个数中选两个,剩一个。

    所以设(f_i,_j)为第(i)轮,剩下第(j)个数时的最小代价

    有三种状态转移(剩第(j)个数(要枚举的)、剩第(2*i)个数、剩第((2*i+1))个数)

    式子:

    [f_{i,j}=min(f_{i,j}, f_{i-1,j}+max(a_{2*i},a_{2*i+1})) ]

    [f_{i,2*i}=min(f_{i,2*i}, f_{i-1,j}+max(a_{j},a_{2*i+1})) ]

    [f_{i,2*i+1}=min(f_{i,2*i+1}, f_{i-1,j}+max(a_{j},a_{2*i})) ]

    但是还要方案,再来一个结构体(path)记录

    (p[i][j].i)(p[i][j].j)记录第(i)层剩第(j)个时选的那两个数,(p[i][j].k)记录上一层剩的是哪个数,以便递归输出。

    注意事项

    一、初始化(f)为INF,(f_{0,1}=0)

    二、(n)++

    这里是为了保证最后一轮时不剩下不该剩下的(1)~(n)

    保证最后一轮剩下的是原来的(n)+(1)

    Code

    #include<bits/stdc++.h>
    using namespace std;
    struct path{int k,i,j;}p[1010][1010];
    int n,ans=1e9,final,a[1010],f[1010][1010];
    inline int read(){
    	int w=0;
    	char ch=getchar();
    	while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9'){
    		w=(w<<3)+(w<<1)+(ch^48);
    		ch=getchar();
    	}
    	return w;
    }
    inline void output(int px, int py){
    	if(px>1) output(px-1,p[px][py].k);
    	if(p[px][py].i>n){printf("%d
    ", p[px][py].j);return;}
    	if(p[px][py].j>n){printf("%d
    ", p[px][py].i);return;}
    	printf("%d %d
    ",p[px][py].i,p[px][py].j);
    	return;
    }
    int main(){
    	n=read();
    	memset(f,0x3f,sizeof(f)); 
    	for(int i=1;i<=n;i++) a[i]=read();
    	n++;
    	f[0][1]=0;
    	for(int i=1;i<=n/2;i++){
    		for(int j=1;j<(i<<1);j++){
    			if(f[i-1][j]+max(a[i<<1],a[i<<1|1])<f[i][j]){
    				f[i][j]=f[i-1][j]+max(a[i<<1],a[i<<1|1]);
    				p[i][j]=(path){j,i<<1,i<<1|1};
     			}
    			if(f[i-1][j]+max(a[j],a[i<<1])<f[i][i<<1|1]){
    				f[i][i<<1|1]=f[i-1][j]+max(a[j],a[i<<1]);
    				p[i][i<<1|1]=(path){j,i<<1,j};				
    			}
    			if(f[i-1][j]+max(a[j],a[i<<1|1])<f[i][i<<1]){
    				f[i][i<<1]=f[i-1][j]+max(a[j],a[i<<1|1]);
    				p[i][i<<1]=(path){j,i<<1|1,j};
    			}
    		}
    	}
    	printf("%d
    ",f[n/2][n]);
    	output(n/2,n);
    	return 0;
    }
    
    

    完结撒花❀

  • 相关阅读:
    HDU 1025 Constructing Roads In JGShining's Kingdom (DP+二分)
    HDU 1158 Employment Planning
    HDU 2059 龟兔赛跑
    Csharp 简单操作Word模板文件
    Csharp windowform datagridview Clipboard TO EXCEL OR FROM EXCEL DATA 保存datagridview所有數據
    Csharp 讀寫文件內容搜索自動彈出 AutoCompleteMode
    Csharp windowform controls clear
    CSS DIV大图片右上角叠加小图片
    Csharp DataGridView自定义添加DateTimePicker控件日期列
    Csharp 打印Word文件默認打印機或選擇打印機設置代碼
  • 原文地址:https://www.cnblogs.com/xxbbkk/p/14071059.html
Copyright © 2011-2022 走看看