Codeforces Round #190 (Div. 1): E. Ciel and Gondolas(決策單調性DP+wqs二分)
阿新 • • 發佈:2018-12-14
題意:
同一道題目,但是bzoj可能需要讀入掛
思路:
沒什麼可講的了
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<string> #include<math.h> #include<queue> #include<stack> #include<iostream> using namespace std; #define LL long long #define mod 1000000007 int n, k, sum[4005][4005]; typedef struct Res { int id; int l, r; }Res; Res q[4005], now; int dp[4005], cnt[4005]; int Cal(int x, int y) { return (sum[y][y]-sum[x-1][y]-sum[y][x-1]+sum[x-1][x-1])/2; } int Check(int i, int j, int k) { int a, b; a = dp[i]+Cal(i+1, k); b = dp[j]+Cal(j+1, k); if(a<b || a==b && cnt[i]<cnt[j]) return 1; return 0; } int Sech(int i, int j, int c) { int l, r, m; l = q[c].l, r = n; while(l<r) { m = (l+r)/2; if(Check(i, j, m)) r = m; else l = m+1; } return r; } int Jud(int val) { int L, R, i, x; L = 1, R = 0; now.id = 0, now.l = 1, now.r = n; q[++R] = now; for(i=1;i<=n;i++) { if(q[L].l>q[L].r) L++; q[L].l++; dp[i] = dp[q[L].id]+Cal(q[L].id+1, i)+val; cnt[i] = cnt[q[L].id]+1; if(R>=L && Check(q[R].id, i, n)) continue; while(R>=L && Check(i, q[R].id, q[R].l)) R--; if(R>=L) { x = Sech(i, q[R].id, R); q[R].r = x-1; now.id = i, now.l = x, now.r = n; } else now.id = i, now.l = i+1, now.r = n; q[++R] = now; } return cnt[n]; } int main(void) { int i, j, x, l, r, m; scanf("%d%d", &n, &k); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { scanf("%d", &x); sum[i][j] = sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+x; } } l = 0, r = sum[n][n]; while(l<r) { m = (l+r)/2; if(Jud(m)<=k) r = m; else l = m+1; } Jud(r); printf("%d\n", dp[n]-k*r); return 0; } /* 9 2 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 */