标签:
第一行为整数L,其中4≤L≤100000,且有50%的数据满足L≤104,表示木板下侧直线段的长。第二行为L个正整数A1,A2,…,AL,其中Ai≤108
仅包含一个整数D,表示为使梳子面积最大,需要从木板上挖掉的格子数。
1 #include<cstring> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 using namespace std; 6 7 #define inf (1LL<<60) 8 #define maxn 100010 9 typedef long long ll; 10 int h[maxn],pp[maxn][32],n; ll f[maxn][2][32],ans=inf,sum; 11 12 int main() 13 { 14 freopen("1200.in","r",stdin); 15 freopen("1200.out","w",stdout); 16 scanf("%d",&n); 17 for (int i = 1;i <= n;++i) 18 { 19 scanf("%d",h+i); sum += h[i]; 20 for (int j = h[i] - 1;j <= h[i] + 1;++j) 21 { 22 pp[i][++pp[i][0]] = j; 23 if (i-1) pp[i-1][++pp[i-1][0]] = j; 24 if (i-2) pp[i-2][++pp[i-2][0]] = j; 25 if (i + 1 <= n) pp[i+1][++pp[i+1][0]] = j; 26 if (i + 2 <= n) pp[i+2][++pp[i+2][0]] = j; 27 } 28 } 29 for (int i = 1;i <= n;++i) 30 { 31 sort(pp[i]+1,pp[i]+pp[i][0]+1); 32 pp[i][0] = unique(pp[i]+1,pp[i]+pp[i][0]+1)-pp[i]-1; 33 while (pp[i][0] && pp[i][pp[i][0]] > h[i]) --pp[i][0]; 34 } 35 memset(f,128,sizeof(f)); 36 for (int i = 1;i <= pp[1][0];++i) f[1][0][i] = f[1][1][i] = pp[1][i]; 37 for (int i = 2;i <= n;++i) 38 for (int j = 1;j <= pp[i-1][0];++j) 39 for (int k = 1;k <= pp[i][0];++k) 40 { 41 if (pp[i-1][j]<pp[i][k]) 42 f[i][0][k] = max(f[i][0][k],f[i-1][1][j]+pp[i][k]); 43 else if (pp[i-1][j]>pp[i][k]) 44 f[i][1][k] = max(f[i][1][k],f[i-1][0][j]+pp[i][k]); 45 else 46 { 47 f[i][0][k] = max(f[i][0][k],f[i-1][0][j]+pp[i][k]); 48 f[i][1][k] = max(f[i][1][k],f[i-1][1][j]+pp[i][k]); 49 } 50 } 51 ans = 1LL<<60; 52 for (int p = 0;p < 2;++p) 53 for (int j = 1;j <= pp[n][0];++j) 54 ans = min(ans,sum-f[n][p][j]); 55 printf("%lld",ans); 56 fclose(stdin); fclose(stdout); 57 return 0; 58 }
标签:
原文地址:http://www.cnblogs.com/mmlz/p/4284968.html