给定一个序列,每次从前三个中选两个值并取他们的最大值累加,不足 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(); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!