标签:space mod cst pre span 思路 i++ 需要 ios
第一行,一个正整数??。
第二行,??个正整数????。
一行,一个整数,需要进行的最小粉刷次数。
5 2 2 1 2 1
3
对于20%的数据,??,???? ≤ 5。
对于50%的数据,??,???? ≤ 200。
对于70%的数据,???? ≤ 3000。
对于100%的数据,?? ≤ 3000,???? ≤ 109。
思路:分治,刷n行油漆,一行一行刷需要n次,
假设最小行高度为t, 如果t>=n,那么最少需要刷
n次,全都竖着刷,如果t<n, 那么可以先横着刷t
次,然后把n个木板分成了若干个连续的部分,然后和刷
n块木板类似,然后比较 t+刷剩下的最小的步数和n比较
#include<stdio.h> #include<algorithm> #include<iostream> #include<cstring> #include<string> #include<queue> #include<map> using namespace std; int mix=1e9+7; int n,ans,a[3300]; int dfs(int c[3300],int n1,int mi) { int d[3300],t=0,mi1=mix,s=0; for(int i=0;i<n1;i++){ if(c[i]-mi>0){ d[t++]=c[i]-mi; if(d[t-1]<mi1) mi1=d[t-1]; } else if(t!=0){ if(mi1<t){ d[t]=0; s=s+min(t,dfs(d,t+1,mi1)); if(s+mi>=n1-1) break; } else{ s=s+t; if(s+mi>=n1-1) break; } t=0;mi1=mix; } } if(n1-1<s+mi) return n1-1; return s+mi; } int main() { scanf("%d",&n); ans=n; int mi=n; for(int i=0;i<n;i++){ scanf("%d",&a[i]); if(mi>a[i]&&a[i]!=0) mi=a[i]; if(a[i]<=0) ans--; } int s=n; if(mi<ans){ s=0; a[n]=0;//最后加个0标记 ans=min(ans,dfs(a,n+1,mi)); } printf("%d",ans); return 0; }
标签:space mod cst pre span 思路 i++ 需要 ios
原文地址:http://www.cnblogs.com/xzxj/p/7875406.html