1. 程式人生 > >洛谷P2389 電腦班的裁員【DP】

洛谷P2389 電腦班的裁員【DP】

時空限制 1000ms / 128MB

題目描述

ZZY有獨特的裁員技巧:每個同學都有一個考試得分ai(-1000<=ai<=1000),在n個同學(n<=500)中選出不大於k段(k<=n)相鄰的同學留下,裁掉未被選中的同學,使剩下同學的得分和最大。要特別注意的是,這次考試答錯要扣分【不要問我為什麼】,所以得分有可能為負。

輸入格式:

第一行為n,k,第二行為第1~n位同學的得分。

輸出格式:

一個數s,為最大得分和。

題目分析

題目資料範圍真的迷,n^2 太小,n^3 太大 dp[i][j][0/1]dp[i][j][0/1]分別表示ii個同學留下jj,且ii個同學不留(0)/留(1)的最大分數

轉移方程為 dp[i][j][0]=max(dp[i1][j][0],dp[i1][j][1])dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]) dp[i][j][1]=max(dp[i1][j][1],dp[i1][j1][0])+a[i]dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j-1][0])+a[i]

#include<iostream>
#include<cmath> #include<algorithm> #include<queue> #include<cstring> #include<cstdio> using namespace std; int read() { int f=1,x=0; char ss=getchar(); while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();} while(ss>='0'&&ss<='9'){x=x*10
+ss-'0';ss=getchar();} return f*x; } const int maxn=510; int n,k; int a[maxn],dp[maxn][maxn][2]; int main() { n=read();k=read(); for(int i=1;i<=n;++i) a[i]=read(); for(int i=1;i<=n;++i) for(int j=1;j<=k;++j) dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]), dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j-1][0])+a[i]; printf("%d",max(dp[n][k][1],dp[n][k][0])); return 0; }