A,B,C都是水题。。。
D题,直接爆搜。我换了好多姿势,其实最简单的方法,就能过。
#include <cstdio> #include <string> #include <cstring> #include <cmath> #include <cstdlib> #include <ctime> #include <queue> #include <vector> #include <map> #include <set> #include <algorithm> #include <iostream> using namespace std; int que[50]; int p[50]; int o[50]; int temp[50]; int st[50]; int ans,minz; int n,a,b; void dfs(int x,int sum) { int i; if(sum >= minz) return; if(x == n) { for(i = 1;i <= n;i ++) temp[i] = p[i]; for(i = 2;i <= n-1;i ++) { temp[i] -= o[i]*a; temp[i-1] -= o[i]*b; temp[i+1] -= o[i]*b; } for(i = 2;i <= n-1;i ++) { if(temp[i] >= 0) break; } if(i == n) { if(sum < minz) { minz = sum; for(i = 2;i <= n-1;i ++) st[i] = o[i]; } } return ; } for(i = 0;i <= 8;i ++) { o[x] = i; dfs(x+1,sum+i); } } int main() { int i,j; scanf("%d%d%d",&n,&a,&b); for(i = 1; i <= n; i ++) { scanf("%d",&p[i]); } while(p[1] >= 0) { que[ans++] = 2; p[1] -= b; p[2] -= a; p[3] -= b; } while(p[n] >= 0) { que[ans++] = n-1; p[n-2] -= b; p[n] -= b; p[n-1] -= a; } for(i = 1;i <= n;i ++) { if(p[i] >= 0) break; } if(i == n+1) { printf("%d ",ans); for(i = 0;i < ans;i ++) printf("%d ",que[i]); printf(" "); return 0; } minz = 1000; dfs(2,0); printf("%d ",minz+ans); for(i = 0;i < ans;i ++) printf("%d ",que[i]); for(i = 2;i <= n-1;i ++) { for(j = 1;j <= st[i];j ++) printf("%d ",i); } printf(" "); return 0; }
E题,二分+rmq之类的,能求区间最值的算法。
题意是比较扯,按章节排列的n本书,要展示,最长能展示多少本,这一段的高度差要小于等于k,再输出总共多少中情况,把起点,终点输出。
rmq好久没写过了啊,记不得 什么东西了。
#include <cstdio> #include <string> #include <cstring> #include <cmath> #include <cstdlib> #include <ctime> #include <queue> #include <vector> #include <map> #include <set> #include <algorithm> #include <iostream> using namespace std; int n,k; int p[100001]; int dpmin[22][100001]; int dpmax[22][100001]; int bin[30]; void CL(int n) { int i,j; for(i = 1;i <= n;i ++) { dpmin[0][i] = p[i]; dpmax[0][i] = p[i]; } for(i = 1;bin[i] <= n;i ++) { for(j = 1;j + bin[i-1] <= n;j ++) { dpmin[i][j] = min(dpmin[i-1][j],dpmin[i-1][j+bin[i-1]]); dpmax[i][j] = max(dpmax[i-1][j],dpmax[i-1][j+bin[i-1]]); } } } int rmqmax(int s,int t) { int k = log((t-s+1)*1.0)/log(2.0); return max(dpmax[k][s],dpmax[k][t-bin[k]+1]); } int rmqmin(int s,int t) { int k = log((t-s+1)*1.0)/log(2.0); return min(dpmin[k][s],dpmin[k][t-bin[k]+1]); } int query(int s,int t) { return rmqmax(s,t) - rmqmin(s,t); } int judge(int mid) { int i,ans = 0; for(i = 1;i <= n-mid+1;i ++) { if(query(i,i+mid-1) <= k) ans ++; } return ans; } int main() { int i,j,str,end,mid; scanf("%d%d",&n,&k); for(i = 1;i <= n;i ++) scanf("%d",&p[i]); bin[0] = 1; for(i = 1;i <= 22;i ++) bin[i] = bin[i-1]*2; CL(n); str = 1; end = n; while(str < end) { mid = (str + end + 1)/2; if(judge(mid)) str = mid; else end = mid - 1; } printf("%d %d ",end,judge(end)); for(i = 1;i <= n-end+1;i ++) { if(query(i,i+end-1) <= k) { printf("%d %d ",i,i+end-1); } } return 0; }