找规律题目总结

最近找规律的题目都写挂了... 我发现是我推理的时候有点小问题 总结一下

相似围栏
(fence.pas/c/cpp)
【问题描述】
何老板购置了一套别墅, 该别墅门口有一片花园, 何老板用 n 块高度不同的木板排成一
排, 搭建了围栏。
一天何老板叫了外卖, 正好是刘郃德骑车送递, 刘被拦在围栏之外, 他发现何老板家的
围栏看起来很好看, 很有高级感。 于是刘郃德也买了 n 块高度不同的木板, 打算参照何老板
的方案, 搭建相似的围栏。 所谓“相似” 是指, 刘郃德的相邻两块木板的高度关系与何老板
对应位置的两块木板的高度关系相同。 比如何老板围栏的第 i 块木板的高度大于第 i+1 块,
那么刘郃德围栏的第 i 块木板的高度也必须大于第 i+1 块。
同时, 刘郃德想要相邻两块木板高度差的绝对值之和尽量大。 请你帮他找出最优方案。

拿到这道题 我首先进行了举例子
1.我想到了要把一些大的或者小的数放到中间 使得代价最大
2.然后我发现了仅为一个峰的情况下 左右两边可以对调 我觉得这很显然 但是我不知道怎么进行排列数
3.然后我利用计算机进行了一波打表 发现一些数可以对调 代价不变

说说我的思路哪里出了问题
第一个问题是觉得显然的东西没有具体证明研究 要是我证明了2 的结论我就可以发现只和波峰波谷有关
第二个问题是我在考虑对调的情况下 还在考虑数怎么排列 应该分开考虑
第三个问题是没有从要求入手 研究绝对值之和的意义
第四个问题是我 图没有画好 就很难看出来规律
第五个是要善于找规律 证明这是为什么

附上代码

//
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxnn 600010
ll n;
ll a[maxnn],b[maxnn];
priority_queue<ll > Q1;
ll tmp1,tmp2;
ll fi,en;
priority_queue<ll,vector<ll > ,greater<ll >  > Q2;
int main() {
	cin>>n;
	for(int i=1; i<=n; i++) {
		scanf("%lld",&a[i]);
	}
	for(int i=1; i<=n; i++) {
		if(i==n) {
			if(a[i-1]<a[i]) {
				tmp1++;
				en=1;
			} else {
				tmp2++;
				en=2;
			}
		} else if(i==1) {
			if(a[i+1]<a[i]) {
				tmp1++;
				fi=1;
			} else {
				tmp2++;
				fi=2;
			}
		} else {
			if(a[i+1]>a[i]&&a[i]<a[i-1]) tmp2++;
			if(a[i+1]<a[i]&&a[i]>a[i-1]) tmp1++;
		}
	}
	for(int i=1; i<=n; i++) {
		scanf("%lld",&b[i]);
		Q1.push(b[i]);
		Q2.push(b[i]);
	}
	ll ans=0;
	while(Q1.size()&&tmp1) {
		ll d=Q1.top();
		Q1.pop();
		ans+=2*d;
		tmp1--;
		if((fi==1)&&(en==1)) {
			if(tmp1<=1) {
				ans-=d;
			}
		} else {
			if(tmp1<=0) {
				if(fi==1) {
					ans-=d;
				}
				if(en==1) {
					ans-=d;
				}
			}
		}
	}
	while(Q2.size()&&tmp2) {
		ll d=Q2.top();
		Q2.pop();
		ans-=2*d;
		tmp2--;
		if((fi==2)&&(en==2)) {
			if(tmp2<=1) {
				ans+=d;
			}
		} else {
			if(tmp2<=0) {
				if(fi==2) {
					ans+=d;
				}
				if(en==2) {
					ans+=d;
				}
			}
		}
	}
	cout<<ans;
}
posted @ 2019-10-31 08:11  ALEZ  阅读(211)  评论(0编辑  收藏  举报