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

一个环上有n个点,价值 a[i],现在要选择m个点,

其中连续段的第一个元素的价值不算,求总和最大?

 

先考虑一条链

f[i][j][0/1] ,j 是目前选择了的点的个数, 0/1 当前点i 是否选择

状态转移:

  f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1])
  f[i][j][1]=max(f[i-1][j-1][0],f[i-1][j-1][1]+a[i])

 

现在考虑环的问题

 

这题发现只有 n 和 1 的位置要多考虑一下,因为n的取法会影响1

我们考虑 元素n是否选择 ,对应dp的边界设置


 // f[1][0][0]=f[1][1][1]=0 
 // f[1][0][0]=0, f[1][1][1]=a[1] 

#include <iostream>
#include <cstring>
using namespace std; 
 const int N=4000;

 int n,m,a[N],f[N][N][2];
 
 void solve(){
 	int i,j;
 	cin>>n>>m;
    for(i=1;i<=n;i++) cin>>a[i];
    
    int ans=-1e9;
    memset(f,-127,sizeof f);
    f[1][0][0]=f[1][1][1]=0;
    
   for(i=2;i<=n;i++)
    for(j=0;j<=m&&j<=i;j++){
      f[i][j][0] =max(f[i-1][j][0],f[i-1][j][1]);
	  f[i][j][1] =max(f[i-1][j-1][1]+a[i],f[i-1][j-1][0]);
    }
    ans=max(ans,f[n][m][0]);
    
    memset(f,-127,sizeof f);
    f[1][0][0]=0,f[1][1][1]=a[1];
    
   for(i=2;i<=n;i++)
    for(j=0;j<=m&&j<=i;j++){
      f[i][j][0] =max(f[i-1][j][0],f[i-1][j][1]);
	  f[i][j][1] =max(f[i-1][j-1][1]+a[i],f[i-1][j-1][0]);
    }
    ans=max(ans,f[n][m][1]);
    cout<<ans<<endl;
 }
 signed main(){ 
    int cas; cin>>cas;
    while(cas--) solve();
    
}


 

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