随笔 - 531  文章 - 0  评论 - 3  阅读 - 10215 

给定一个序列,每次从前三个中选两个值并取他们的最大值累加,不足 3 个就取剩下的 1 个或 2 个的最大值累加,

求和的最小值以及取法。

 

每一次会取两个数,也就是会剩下一个数,所以我们可以把剩下的那个数来设状态

  F[ i] [j ] 前i个数,剩余的数为j

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int N =1003;
struct T{
    int k,i,j;
}p[N][N];
int n,f[N][N],a[N];
 
 void print(int x,int y){
    if(x>1) print(x-1,p[x][y].k);
    if(p[x][y].i>n){printf("%d\n", p[x][y].j);return;}
    if(p[x][y].j>n){printf("%d\n", p[x][y].i);return;}
    printf("%d %d\n",p[x][y].i,p[x][y].j);
 }
 void solve(){
    int i,j;
    memset(f,127,sizeof f);
    cin>>n;for(i=1;i<=n;i++) cin>>a[i]; n++;
     
    f[0][1]=0;
    for(i=1;i<=n/2;i++)
    for(j=1;j<i*2;j++){
        if(f[i][j]>f[i-1][j]+max(a[i*2],a[i*2+1]))
            f[i][j]=f[i-1][j]+max(a[i*2],a[i*2+1]),
            p[i][j]=T{j,i*2,i*2+1};
             
        if(f[i][2*i]>f[i-1][j]+max(a[i*2+1],a[j]))
            f[i][2*i]=f[i-1][j]+max(a[i*2+1],a[j]),
            p[i][2*i]=T{j,i*2+1,j};
         
        if(f[i][2*i+1]>f[i-1][j]+max(a[i*2],a[j]))
        f[i][2*i+1]=f[i-1][j]+max(a[i*2],a[j]),
        p[i][2*i+1]=T{j,i*2,j};
    }
         
    cout<<f[n/2][n]<<endl; print(n/2,n);
 }
 signed main(){
    solve();
 }

 

posted on   towboat  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示