Codeforces 1077F1 Pictures with Kittens (easy version)(DP)
题目链接:Pictures with Kittens (easy version)
题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和。
题解:$dp[i][j]$:以i为结尾选择j个数字的最大和。
$dp[i][j]=max(dp[i][j],dp[s][j-1]+a[i])$,$s为区间[i-k,i)$。
以i为结尾的最大和可以由i之前k个位置中的其中一个位置选择j-1个,再加上当前位置的ai得到。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 typedef long long ll; 8 const int N=200+10; 9 ll a[N],dp[N][N],ans=-1e18; 10 11 int main(){ 12 int n,k,x; 13 scanf("%d%d%d",&n,&k,&x); 14 for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 15 16 for(int i=0;i<=n;i++) 17 for(int j=0;j<=n;j++) 18 dp[i][j]=-1e18; 19 20 dp[0][0]=0; 21 22 for(int j=1;j<=x;j++){ 23 for(int i=1;i<=n;i++){ 24 for(int s=max(0,i-k);s<i;s++){ 25 dp[i][j]=max(dp[i][j],dp[s][j-1]+a[i]); 26 } 27 } 28 } 29 30 for(int i=n-k+1;i<=n;i++) ans=max(ans,dp[i][x]); 31 if(ans<0) ans=-1; 32 33 printf("%lld\n",ans); 34 return 0; 35 }