首页 > 其他分享 >[ZJOI2020] 序列 线性规划做法/贪心做法

[ZJOI2020] 序列 线性规划做法/贪心做法

时间:2023-05-02 19:46:32浏览次数:48  
标签:线性规划 geq cdot max leq ZJOI2020 做法 aligned 贪心

线性规划做法

同时也作为线性规划对偶的一个小小的学习笔记。

以下 \(\cdot\) 表示点积,\(b,c,x,y\) 是行向量。

\(A\) 是矩阵,对于向量 \(u,v\) 若 \(\forall i,u_i\leq v_i\) 则称 \(u\leq v\),\(\geq\) 同理。

线性规划标准型:

\[\max c\cdot x\\ s.t. \left\{ \begin{aligned} &Ax\leq b \\ &x\geq 0 \end{aligned} \right. \]

它的对偶是:

\[\min b\cdot y \\ s.t. \left\{ \begin{aligned} &A^Ty\geq c \\ &y\geq 0 \end{aligned} \right. \]

弱对偶定理:\(\max c\cdot x \leq \min b\cdot y\)。

我们可以任意取可行域中的 \(x,y\),然后对于 \(y^TAx\) 一方面由于 \(y^T\) 非负有 \(y^TAx\leq y^T b=b\cdot y\),另一方面 \(y^TAx=(yA^T)^Tx\geq c^Tx=c\cdot x\),即得证。

强对偶定理:\(\max c\cdot x = \min b\cdot y\)。也就是说我们可以把线性规划转为其对偶问题进行求解。

回到这道题,给每一个区间的每一种操作编号 \(1\sim M\),对于第 \(t\) 个操作设其下标集合为 \(I_t\),我们建一个变量 \(x_t\),表示这个操作重复做的次数。我们放宽 \(x_t\in R\),可以证明最优解仍然是整数。

将取等条件拆成两个条件,那么答案是:

\[\min \sum_{t=1}^M x_t\\ s.t. \left\{ \begin{aligned} &\sum_{t=1}^{M} [i\in I_t] x_t\geq a_i \\ &-\sum_{t=1}^{M} [i\in I_t] x_t\geq -a_i \\ &x_t\geq 0 \end{aligned} \right. \]

对偶一下,有:

\[\max \sum_{i=1}^n a_i(p_i-q_i)\\ s.t. \left\{ \begin{aligned} &\sum_{i=1}^{n} [i\in I_t](p_i-q_i)\leq 1 \\ &p_i,q_i\geq 0 \end{aligned} \right. \]

容易发现 \(p_i-q_i\) 可以取任意实数,设 \(y_i=p_i-q_i\),有:

\[\max \sum_{i=1}^n a_i y_i\\ s.t. \sum_{i=1}^{n} [i\in I_t]y_i\leq 1 \]

这里 yhx 大佬的博客中讲此矩阵是全单模矩阵,也就是说线性规划可行域的顶点全是整数所以这个线性规划具有整数性?不太了解什么是全单模 QAQ。

既然有整数性,那么考虑拿着这个东西做。该线性规划的实际意义是让我们对每个位置赋权,使得每种操作下标的权值之和都 \(\leq 1\)。

经典套路,类似最大子段和,记录三种操作后缀和的最大值 \(x,y,z\) 来 DP。由限制有 \(x,y,z\leq 1\)。而如果有 \(x/y/z<0\),那么我们就需要”截断“然后新开一个后缀。同时这也说明了 \(y_i\) 有意义的取值只有 \(0,1,-1\),\(<-1\) 的都是”截断“而总权值没有 \(-1\) 优秀所以一定不会取。

时间复杂度 \(O(n)\) 带 \(24\) 的常数。

#include <cstdio>
#include <algorithm>
#define forxyz \
	for(int x=0;x<2;++x) \
		for(int y=0;y<2;++y) \
			for(int z=0;z<2;++z)
using namespace std;
int read(){
	char c=getchar();int x=0;
	while(c<48||c>57) c=getchar();
	do x=(x<<1)+(x<<3)+(c^48),c=getchar();
	while(c>=48&&c<=57);
	return x;
}
typedef long long ll;
const int N=100003;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n;
int a[N];
ll f[N][2][2][2];
void solve(){
	n=read();
	for(int i=1;i<=n;++i) a[i]=read();
	for(int i=1;i<=n;++i) forxyz f[i][x][y][z]=-INF;
	f[0][0][0][0]=0;
	for(int i=1;i<=n;++i){
		forxyz{
			for(int d=-1;d<=1;++d){
				if(x+d>1||y+d>1) continue;
				ll &dp=f[i][max(x+d,0)][z][max(y+d,0)];
				dp=max(dp,f[i-1][x][y][z]+d*a[i]);
			}
		}
	}
	ll res=0;
	forxyz res=max(res,f[n][x][y][z]);
	printf("%lld\n",res);
}
int main(){
	int tc=read();
	while(tc--) solve();
	return 0;
}

贪心做法

解析咕了,具体看洛谷题解区。

#include <cstdio>
#include <algorithm>
using namespace std;
int read(){
	char c=getchar();int x=0;
	while(c<48||c>57) c=getchar();
	do x=(x<<1)+(x<<3)+(c^48),c=getchar();
	while(c>=48&&c<=57);
	return x;
}
typedef long long ll;
void solve(){
	int n=read();
	ll a=0,b=0,c=0,res=0,las=read();
	for(int i=2;i<=n+1;++i){
		ll x=0;
		if(i<=n) x=read();
		ll dlt=0;
		if(x<a+b){
			dlt=a+b-x;
			if(a<dlt) b-=dlt-a,dlt=a;
			if(b<dlt) a-=dlt-b,dlt=b;
			a-=dlt;b-=dlt;x-=dlt;
		}
		x-=a+b;
		ll mn=min(las,x);
		res+=mn;las-=mn;x-=mn;a+=mn;
		res+=las;c+=las;
		x+=dlt;res-=dlt;
		las=x;
		swap(b,c);
	}
	printf("%lld\n",res);
}
int main(){
	int tc=read();
	while(tc--) solve();
	return 0;
}

标签:线性规划,geq,cdot,max,leq,ZJOI2020,做法,aligned,贪心
From: https://www.cnblogs.com/yyyyxh/p/ZJOI_sequence.html

相关文章

  • POJ--1328 Radar Installation(贪心)
    记录0:502023-5-1http://poj.org/problem?id=1328reference:《挑战程序设计竞赛(第2版)》第二章练习题索引p135DescriptionAssumethecoastingisaninfinitestraightline.Landisinonesideofcoasting,seaintheother.Eachsmallislandisapointlocating......
  • 题目 3158: 蓝桥杯2023年第十四届省赛真题-三国游戏(贪心)
    题目描述小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵X,Y,Z(一开始可以认为都为0)。游戏有n个可能会发生的事件,每个事件之间相互独立且最多只会发生一次,当第i个事件发生时会分别让X,Y,Z增加Ai,Bi,Ci。当游戏结束时(所有事件的发生与否已......
  • APEX中:Dialog的做法(1):利用分支branch跳转 但是需要有提交
    ​APEX中:Dialog的做法(1):利用分支branch跳转但是需要有提交的动作 本文由OracleApex中文社区纯手工打造,希望初学朋友也能一看就明白!!原文以及本篇涉及第二部分Dialog的做法(2)请到:https://www.sqlu.cn/85.html查阅1:先做好一个Dialog类型的页面Page46;创建页面=>空白......
  • B. Sum of Two Numbers - 贪心+思维+构造
    题意:给定一个整数n,输出x,y满足以下要求:1.x+y=n2.x的每一位上的数加在一起的数位和和y的数位和相差不超过1.分析:从高位开始依次遍历,将其平均分给x和y,奇数剩余的1由x和y轮流加上。代码:#include<bits/stdc++.h>#defineendl'\n'usingnamespacestd;......
  • B. Equalize by Divide - 贪心+思维+构造+数学+排序
    题意:给定一个数组,可以进行任意多次以下操作:1.选择第i和第j个数。2.使a[i]=a[i]/a[j](向上取整)。不可以插入或者删减数组元素,求多少次使数组元素都相同,输出次数以及每次操作的两个下标i,j;如果无法实现输出-1.分析:数组中存在1一定无法实现,或者数组元素都相......
  • 贪心(区间选点)
    #include<bits/stdc++.h>usingnamespacestd;constintN=1e5+10;intn;structRange{intl;intr;booloperator<(constRange&w)const{returnr<w.r;}}range[N];intmain(){intn;cin>>n;for(inti=0;i<......
  • 2023-04-24 算法面试中常见的贪心算法问题
    贪心算法1贪心选择例题455.饼干分配假设你想给小朋友们饼干。每个小朋友最多能够给一块儿饼干。每个小朋友都有一个“贪心指数”,称为g(i),g(i)表示的是这名小朋友需要的饼干大小的最小值。同时,每个饼干都有一个大小值s(i)。如果s(j)>=g(i),我们将饼干j分给小朋友i后,小朋友就会......
  • XI Samara Regional Intercollegiate Programming Contest Problem K. Video Reviews
    Thestudio«LodkaGaming»isengagedinadvertisingoftheirnewgame«.C.O.N.T.E.S.T:UnexpectedBehaviour».Thestudio’smarketerisplanningtocommunicatewithnvideobloggersonebyone(inthepredeterminedorder,startingfromthe1-standend......
  • POJ - 3614 贪心
    Toavoidunsightlyburnswhiletanning,eachoftheC(1≤C≤2500)cowsmustcoverherhidewithsunscreenwhenthey’reatthebeach.CowihasaminimumandmaximumSPFrating(1≤minSPFi≤1,000;minSPFi≤maxSPFi≤1,000)thatwillwork.Ifthe......
  • 4.24 贪心法学习笔记
    多写题解多交流才能学好oi。在这里贴了代码,为了看上去完整一些。 大概是一些自己学习的记录罢。贪心不算客观意义上的算法,感觉还不算一种策略机制。我认为更像一种思路,其内涵就是择优,解题时就去想怎样才能更优。根据最优的思路能去做很多,如果说贪心是一个题的正解的话太抽......