D. Two out of Three
设fi,jf_{i,j}fi,j表示为当前队伍开头的两个人是i,ji,ji,j时最小代价,分析可知本轮可以选择的方案有
- i,ji,ji,j两人,fi,j=ai+aj+fj+1,j+2f_{i,j}=a_i+a_j+f_{j+1,j+2}fi,j=ai+aj+fj+1,j+2
- i,j+1i,j+1i,j+1两人,fi,j=ai+aj+1+fj,j+2f_{i,j}=a_i+a_{j+1}+f_{j,j+2}fi,j=ai+aj+1+fj,j+2
- j,j+1j,j+1j,j+1两人,fi,j=aj+aj+1+fi,j+2f_{i,j}=a_{j}+a_{j+1}+f_{i,j+2}fi,j=aj+aj+1+fi,j+2
记忆化搜索记录即可。
LCGUO题解
#include<bits/stdc++.h>using namespace std;constexpr int N=1010;
int n;
int a[N],f[N][N];
int dfs(int x,int y)
{if(f[x][y]) return f[x][y];if(y==n+1) return f[x][y]=a[x];if(y==n) return f[x][y]=max(a[x],a[y]);f[x][y]=max(a[x],a[y])+dfs(y+1,y+2);f[x][y]=min(f[x][y],max(a[x],a[y+1])+dfs(y,y+2));f[x][y]=min(f[x][y],max(a[y],a[y+1])+dfs(x,y+2));return f[x][y];
}
void print(int x,int y)
{if(y==n+1) return cout<<x<<'\n',void();if(y==n) return cout<<x<<' '<<y<<'\n',void();if(f[x][y]==max(a[x],a[y])+f[y+1][y+2])cout<<x<<' '<<y<<'\n',print(y+1,y+2);else if(f[x][y]==max(a[x],a[y+1])+f[y][y+2])cout<<x<<' '<<y+1<<'\n',print(y,y+2);else if(f[x][y]==max(a[y],a[y+1])+f[x][y+2])cout<<y<<' '<<y+1<<'\n',print(x,y+2);}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n;for(int i=1;i<=n;i++) cin>>a[i];cout<<dfs(1,2)<<'\n';print(1,2);return 0;
}