版权声明:请大家斧正,如喜欢的话,为拙见点一个赞吧。 https://blog.csdn.net/qq_39897867/article/details/86729931
题目
Description
Zagreb大学的ACM队伍(由三个人组成)正在打Final。他们的技术指导提出了一个牛逼的策略如下。
在一开始,队伍的每一个人会评估每一道题的难度,难度会用1~5的整数表示,数字越大题目越难。然后他们会分配题目给每个人。题目会分成三个部分,每个队员会拿到一个非空的连续的题目代表了他要解决的问题。他们的策略是让难度评估系数最小。难度评估系数是三个队员对各自所拿到题目的难度评估的总和。你的任务是计算这个最小的难度评估系数。
Input
第一行包括了一个整数N(3<=N<=150000),代表题目数量。
接下来的三行,每行N个1~5的整数,每一行代表一个队员对N道题的难度评估。
Output
输出一个整数。代表最小的难度评估系数。
结题思路
比赛时打了一个WA的暴力。 对于正解:
-
+斜率优化(这种东西
不存在的)
设
表示目前是第i个人第j件物品时的最小难度评估系数。
动态转移方程为:
注意常数
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fre(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#define rep(i,x,y) for(register int i=x;i<=y;i++)
using namespace std;
int n,f[4][150001],ans=0x3f3f3f3f,a[4][150001];
void aa(){swap(a[2],a[3]);}
void bb(){swap(a[1],a[2]);}
void dp(){
memset(f,0x3f3f3f3f,sizeof(f)); f[0][0]=0;
rep(i,1,3) rep(j,1,n) f[i][j]=min(f[i][j-1],f[i-1][j-1])+a[i][j];
ans=min(ans,f[3][n]);
}
int main(){
// fre(acm);
scanf("%d",&n);
rep(i,1,3) rep(j,1,n) scanf("%d",&a[i][j]);
dp(); aa(); dp(); bb(); dp(); aa(); dp(); bb(); dp(); aa(); dp();
printf("%d",ans);
}