链接:
题意:
一个长度3n的环,选n次数字,每次选完以后相邻的数字会消失,求选取结果最大值
解:
这波是~~(ctrl)CV工程师了~~
核心思想是选取n个不相邻的元素一定合法,我推不出来,猜一猜倒是可以O.o
DP[i][j]
表示从[0,i]
中选取j
个数字的最大值
初始条件,我们可以确定,如果选择0个数字j==0
则结果为0;如果j<i+1
,,则要在不足的数字中进行选取,我们设为0(官方是设为INT_MIN,我写了0好像也没事,可能是数据弱了?);由于思想中只对相邻数字做判断,所以我们提供[0,0]和[0,1]
选取1个数字的值作为DP的初始条件之一,即dp[0][1]=temp[0] 和 dp[1][1]=max(temp[0],temp[1])
剩下的就很简单了,状态转移就是从小的范围推导出大的范围,少的选取推导出多的选取,每个DP[I][J]
只需要判断I
选不选就行
特别注意的是,由于整体成环状,所以分别对去掉头和去掉尾进行一次DP(因为只考虑相邻)
只要能推出取n个不相邻的数字就能满足题意就很好写了
实际代码:
#include<bits/stdc++.h>
using namespace std;
int solve(vector<int>& temp)
{
int num=temp.size(),need=(num+1)/3;
vector<vector<int>>dp(num,vector<int>(need+1,0));
dp[0][1]=temp[0];
dp[1][1]=max(temp[0],temp[1]);
for(int i=2;i<num;i++)
{
for(int j=1;j<=need;j++)
{
dp[i][j] = max(dp[i - 1][j],dp[i - 2][j - 1]+temp[i]);
}
}
return dp[num-1][need];
}
int maxSizeSlices(vector<int>& slices)
{
int lg=slices.size();
vector<int> v1(slices.begin() + 1, slices.end());
vector<int> v2(slices.begin(), slices.end() - 1);
return max(solve(v1),solve(v2));
}
int main()
{
vector<int> slices;int slice;
while(cin>>slice) slices.push_back(slice);
int ans=maxSizeSlices(slices);
cout<<ans<<endl;
return 0;
}
限制:
1 <= slices.length <= 500
slices.length % 3 == 0
1 <= slices[i] <= 1000