首页 > 其他分享 >Lyk Love painting

Lyk Love painting

时间:2022-09-28 20:44:11浏览次数:47  
标签:f1 魅力值 Love define while 矩形 painting dp Lyk

Lyk Love painting

一道超出常规的动态规划

题干

【题目描述】

lyk有一块神奇的画布,呈2*n的格子状。lyk现在想在画布上画m幅画,每幅画必须是矩形。为了充分利用画布,画布上的每一个格子都必须属于某一幅画。

每一个格子都有一个魅力值,一幅画的魅力值为其所包含的格子的魅力值的总和。为了不过于展现自己的才华lyk希望这m幅画魅力值的最大值最小。然而他并不知道如何作画才能达到要求,请你帮帮他吧。

【输入】

第一行两个数n,m

第2、第3行每行n个数,表示每个格子的魅力值

【输出】

仅包含一个整数,为最优方案中最大的魅力值最小可能为多少。

【输入样例】

3 3
1 3 2
1 3 2

【输出样例】

4

【提示】

【数据范围】

对于30%的数据,n ≤ 150, m ≤ 30

对于60%的数据,n ≤ 500, m ≤ 50

对于80%的数据,n ≤ 2000, m ≤ 100

对于100%的数据,n ≤ 100000, m ≤ 100

做法:

首先,看到希望使得最大魅力值最小,非常显然的二分答案
于是难点来到如何去\(check\)答案。

题意实际要求我们做的是将一个\(2*n\)的矩形分割成若干个小矩形,因为二分答案,所以我们要在限定的取值下分割成限定的块
又由于,当较优的划分成立时,较差的一定可以成立。因此我们只要在分割时保证最优策略,检查最优策略是否能在不超过\(mid\)的前提下,划分成小于等于\(m\)个块,就可以判定答案的可行性了。
这似乎很麻烦,但幸运的是,由于画布是2*n的大矩形,所有的矩形实际上只有以下3种情况

如果假设我们已经铺好了所有的矩形,最后的划分状态一定是一整块竖向的矩形,或者两块由一定数量的小矩形组成的横向的矩形两种情况组成的,也就是

可以想到,对于最终得到的矩形一定是一段一段的(也有可能只有一段),
这样的话,我们可以将每一个完整的一段作为一个状态,进行转移,也就是,动态规划

于是,我们考虑使用动态规划。
设\(dp[i]\)表示,前\(i\)都已划分好,且最后一块右端为第\(i\)列时,已划分的块数。考虑转移的两张情况,一种为前面提到的"1"矩形,另一种就是由多个"2","3"矩形进行填充。根据最优策略,很容易能想到,这一块中的矩形在总魅力值小于等于限制的前提下,越长越好。
先看朴素方法,对第一种情况,我们直接从左往右找到第一个符合条件的位置j,直接转移即可。对情况二,我们采取同样的方法,但对上下两部分分别进行,各自多次向前找到最长的块,直到无法继续向前为止,次数终止于j2列。
于是得到转移方程

\[dp[i]=min(dp[j_1]+cost(i,j_1),dp[j_2]+\sum_{k=1}^{k<=j_2}) \]

但是,这种方式下的复杂度为\(O(n^2mlogn)\),很显然无法通过此题。
考虑对转移的优化。
二分答案时,对于不同的限制值,分别预处理出每一列的三种情况(就是前面的那三个矩形)下向前转移的最远位置,\(pre1[]\),\(pre2[]\),\(pre3[]\)。

这样,我们用\(O(n)\)的时间预处理后,就可以在转移时\(O(1)\)地得到每一个最佳决策。
最终复杂度为\(O(nmlgn)\)。

coding:

#include<bits/stdc++.h>
#define N 1000005
#define max(a,b) a>b?a:b
#define f1(i,n,m) for(int i=n;i<=m;++i)
#define f2(i,n,m) for(int i=n;i>=m;--i)
#define ll long long 
#define reset(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f
using namespace std;
template <typename T>
void read(T &x){
    int w=1;x=0;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    x*=w;
}
int n,m;
ll l,r,mid;
ll v[5][N],pre1[N],pre2[N],pre3[N];
ll s1[N],s2[N],s3[N];
int dp[N];
inline bool check(ll lim){	
	pre1[0]=pre2[0]=pre3[0]=0;
	f1(i,1,n){
		pre1[i]=pre1[i-1],pre2[i]=pre2[i-1],pre3[i]=pre3[i-1];
		while(s1[i]-s1[pre1[i]]>lim)pre1[i]++;
		while(s2[i]-s2[pre2[i]]>lim)pre2[i]++;
		while(s3[i]-s3[pre3[i]]>lim)pre3[i]++;
	}
	reset(dp,INF);
	dp[0]=0;
	int step,p1,p2;
	f1(i,1,n){
		dp[i]=min(dp[i],dp[pre3[i]]+1);
		p1=p2=i,step=0;
		while(step<=m&&(p1||p2)){
			if(p1>p2)p1=pre1[p1];
			else p2=pre2[p2];
			step++;
			dp[i]=min(dp[i],dp[max(p1,p2)]+step);
		}
		if(dp[i]>m)return false;	
	}
	return true;
}
signed main(){
	// freopen("paint.in","r",stdin);
	// freopen("paint.out","w",stdout);
	read(n),read(m);
	f1(i,1,2)f1(j,1,n)read(v[i][j]),l=max(v[i][j],l);
	f1(i,1,n){		
		s1[i]=s1[i-1]+v[1][i];
		s2[i]=s2[i-1]+v[2][i];
		s3[i]=s1[i]+s2[i];
	}
	r=s3[n];
	while(l<r){
		mid=(l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
		// cout<<l<<" "<<r<<"\n";
	}
	printf("%lld\n",r);
	return 0;
}

圆满结束

标签:f1,魅力值,Love,define,while,矩形,painting,dp,Lyk
From: https://www.cnblogs.com/windf/p/16739237.html

相关文章

  • Arc SQL MI: Multi-cloud Database failover using Distributed AG
    Reference:https://techcommunity.microsoft.com/t5/azure-architecture-blog/arc-sql-mi-demonstrating-multi-cloud-database-failover-using/ba-p/2936589architect......
  • 【题解】DZY Loves Math V
    题目描述给你\(n\)个整数\(a_i\)叫你求:\[\sum_{i_1|a_1}\sum_{i_2|a_2}\sum_{i_3|a_3}\cdots\sum_{i_n|a_n}\varphi(i_1i_2i_3\cdotsi_n)\]简要思路发现对于欧拉......
  • CF1720E Misha and Paintings 题解
    神仙2700。首先统计出原数组中不同元素个数记作\(cnt\),如果\(cnt\lek\)说明元素个数不够,由于一次只能加一个颜色因此答案就是\(k-cnt\)。然后接下来要证明一个结论......
  • [极客大挑战 2019]LoveSQL 1
    很明显这时一道SQL注入的题目这题很简单的SQL注入题目,使用union(联合查询注入),但是缠了我很久为什么呢?因为我们学校的waf,很多可以注入成功的语句,他都会连接被重置,或者被b......
  • Painting Game (博弈论)
    题目:  VirtualJudge(vjudge.net)题目大意:2个人轮流对长条方格填黑,黑的地方不能够相邻.一个人要尽量填黑,一个人要尽量不填黑,当不能填的时候就结束题解思路:......
  • CF446C DZY Loves Fibonacci Numbers
    CF446CDZYLovesFibonacciNumbers题目大意在本题中,我们用\(f_i\)来表示第\(i\)个斐波那契数(\(f_1=f_2=1,f_i=f_{i-1}+f_{i-2}(i\ge3)\))。维护一个序列\(a\),长......
  • CF1720E. Misha and Paintings
    题意给出n*n的矩阵,ai,j∈[1,n*n],现在要矩形覆盖若干次,每次把一个正方形的ai,j改为x,求最少的次数使得最后有k种不同的数n<=500题解设sum为初始不同的数,若sum<k则显然只......
  • Codeforces Round #815 (Div. 2) E. Misha and Paintings
    人生中第一个AC的codeforces题,大概太难了,光是看答案就看了整整一下午,最后还是在b站上搜到讲解视频才明白的。俺们阿B真的是太厉害啦这道题首先容易看出当矩阵中数字个数......
  • 1032 Rinne Loves Dynamic Graph 循环分层图 最短路
     链接:https://ac.nowcoder.com/acm/contest/26077/1032来源:牛客网题目描述Rinne学到了一个新的奇妙的东西叫做动态图,这里的动态图的定义是边......
  • 1031 Rinne Loves Graph 求经过k个障碍到达n的最短路 分层图或最短路+dp
     链接:https://ac.nowcoder.com/acm/contest/26077/1031来源:牛客网题目描述Island发生了一场暴乱!现在Rinne要和Setsuna立马到地上世界去。......