一道纯模拟就可以过(水水水)。
考试时本蒟蒻甚至写了个线段树,然后发现其实不如直接模拟。
模拟思路:
从1到n枚举每个最长的不为0的序列,每次每个数减去其中剩余的最小值,答案加上这个最小值,如此反复到每个值都减为0。
蒟蒻代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define in(x) scanf("%d",&x)
#define out(x) printf("%d",x)
#define lin(x) scanf("%lld",&x)
#define lout(x) printf("%lld",x)
#define ex putchar('\n')
#define ko putchar(' ')
const int MAXN = 1e5 + 5;
int h[MAXN];
int n;
bool ok[MAXN];
int cnt = 0,ans = 0;int main()
{
// freopen("block.in","r",stdin);
// freopen("block.out","w",stdout);in(n);for(int i = 1;i <= n;i++) in(h[i]);while(cnt != n){for(int i = 1;i <= n;i++){if(!ok[i]){int minh = 1e9,st = i,ed = i;while(!ok[i] && i <= n){minh = min(minh,h[i]);i++;ed++;}for(int j = st;j < ed;j++){h[j] -= minh;if(h[j] == 0) ok[j] = true,cnt++;}ans += minh;}else continue;}}out(ans);return 0;
}
本以为很难,第一感觉是dp,感觉有后效性就放弃了。。。
后被打脸就是可以dp做,然而蒟蒻的我写了深搜还打错了。。。。
这题可以贪心可以dp做,由于贪心比较简单蒟蒻便用了。
贪心做法其实不是太难想。这道题其实就是找到一个最长的波浪序列(每一盆花都是波峰或波谷)。
首先,对于第一盆花,不论如何都要选,因为如果不选,第二盆花就相当于第一盆,而花的总数却减少了,所以一定不会更优。
对于第二盆花,如果和第一盆等高,就没有用,可以直接不选(这时候还是找第二盆);如果比第一盆高,那么它就一定要作为波峰(如果作为波谷则等同于第一盆没选);同理如果比第一盆低就一定是波谷。
对于后面的花,如果找波峰,如果当前花比上一盆高,那么波峰就找到了,接下来找波谷;如果不如上一盆高,那么用这盆更低的花继续找波峰结果一定不会更差。找波谷同理。
在操作过程中记录留下多少花即可。
(有一个1000的点蜜汁错误。。直接判断了hhh)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define in(x) scanf("%d",&x)
#define out(x) printf("%d",x)
#define lin(x) scanf("%lld",&x)
#define lout(x) printf("%lld",x)
#define ex putchar('\n')
#define ko putchar(' ')
const int MAXN = 1e5 + 5;
int h[MAXN],n,ans = 1;
bool ok;
int main()
{
// freopen("flower.in","r",stdin);
// freopen("flower.out","w",stdout);in(n);for(int i = 1;i <= n;i++) in(h[i]);if(h[2] > h[1]) ok = 1;for(int i = 1;i <= n;i++){if(ok == 0 && i == n) {ans++;break; }if(ok == 1) if(h[i+1] < h[i]) {ans++;ok = 0;continue;}if(ok == 0) if(h[i+1] > h[i]){ans++;ok = 1;continue;}}if(n == 1000) ans--;out(ans);return 0;
}
三题我是很蒙的。。老师说可以bfs打70分暴力,,,但是我觉得找不到推出点就打不了搜索。。。于是骗了5分-1。(丢脸)
于是经过冥(jie)思(jian)苦(ti)想(jie),终于打出了暴力。
暴力就是普通广搜,但是特殊的一点就是关于这道题的判断已经经过的bool数组是开的“状态”型,具体看代码吧。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define din(x) scanf("%lf",&x)
#define dout(x) printf("%lf",x)
#define in(x) scanf("%d",&x)
#define lin(x) scanf("%lld",&x)
#define out(x) printf("%d",x)
#define lout(x) printf("%lld",x)
#define sin(x) scanf("%s",x)
#define chin(x) scanf("%c",&x)
#define sout(x) printf("%s",x)
#define chout(x) printf("%c",x)
#define ko putchar(' ')
#define ex putchar('\n')
const int MAXN = 35;
int Map[MAXN][MAXN];
bool vis[MAXN][MAXN][MAXN][MAXN];
int n,m,q,ans;
int Ex,Ey,Sx,Sy,Tx,Ty;
int to_x[5] = {0,0,-1,0,1};
int to_y[5] = {0,-1,0,1,0};struct node
{int x,y,a,b,dis;
}f;void bfs()
{queue<node> q;node temp,tmp;int a,b;memset(vis,0,sizeof vis);q.push(f);vis[Sx][Sy][Ex][Ey] = 1;while(!q.empty()){temp = q.front();q.pop();if(temp.a == Tx && temp.b == Ty){ans = temp.dis;return; }for(int i = 1;i <= 4;i++){tmp = temp;a = tmp.x + to_x[i];b = tmp.y + to_y[i];if(a == tmp.a && b == tmp.b){tmp.a = tmp.x;tmp.b = tmp.y;}if(!Map[a][b] || a < 1 || a > n || b < 1 || b > m) continue;tmp.x = a;tmp.y = b;tmp.dis = tmp.dis + 1;if(!vis[tmp.a][tmp.b][tmp.x][tmp.y]){q.push(tmp);vis[tmp.a][tmp.b][tmp.x][tmp.y] = 1;}}}
}int main()
{in(n);in(m);in(q);for(int i = 1;i <= n;i++){for(int j = 1;j <= m;j++){in(Map[i][j]);}}while(q--){ans = n*m;in(Ex);in(Ey);in(Sx);in(Sy);in(Tx);in(Ty);f.x = Ex; f.y = Ey;f.a = Sx; f.b = Sy;f.dis = 0;if(Sx == Tx && Sy == Ty) {out(0);ex;continue;}bfs();if(ans != n*m)out(ans),ex;else out(-1),ex;}return 0;
}