CF321E Ciel and Gondolas Wqs 2분 사각형 부등식 최적화 dp 결정 단조성

3606 단어
LINK:CF321E Ciel and Gondolas
이렇게 재미있는 제목은 매우 드물다.틀에 박힌 말이지만...
쉽게 생각할 수 있는 dp\(f {i, j}\) 는 이전 i단이 j단으로 나뉘어 있는 최소값 이동을 표시하기 위해서\(cost (i, j)\를 유지해야 한다는 것을 나타낸다.
폭력은 분명 불가능하지만 폭력 매거 결정은 접두사와 선형으로 미리 처리할 수 있다.
분명히 의사결정을 최적화하려면 첫 번째 단계에서 O(1)\(cost(i, j)\)를 구해야 한다.
그림% 1개의 캡션을 편집했습니다.
dp 이동식을 관찰한 결과 이것은 전형적인 사각형 부등식 최적화 dp 세트 사용 결정의 단조성 복잡도\(n\cdot k\cdot logn\)
강제 k단은 분명히 Wqs2점으로 제한을 해제할 수 있지만 이렇게 나누기는 쉽지 않습니다. 단조로운 대기열로 해야 합니다.
그런데 문제가 하나 있는데mid가 있을 때 k-1mid+1일 때 k+1일 수도 있어요.
이 문제에 관해서는 값이 같을 때 단을 많이 나누는 방법을 통해 위의 상황을 합법화시켜 최종적으로 >=k일 수 있지만 여전히 k와 같은 상황을 구성할 수 있다.
만약 소수 2점이라면 분명히 필요없을 것이다. 왜냐하면 고정된 점까지 정확할 수 있기 때문이다.
총 복잡성\n\cdot logMx\cdot logn\)
code
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define db double
#define INF 10000000000000010ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d
",x) #define putl(x) printf("%lld
",x) #define gc(a) scanf("%s",a+1) #define rep(p,n,i) for(RE int i=p;i<=n;++i) #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]]) #define fep(n,p,i) for(RE int i=n;i>=p;--i) #define vep(p,n,i) for(RE int i=p;i #define mk make_pair #define RE register #define P 1000000007 #define gf(x) scanf("%lf",&x) #define pf(x) ((x)*(x)) #define uint unsigned long long #define ui unsigned #define EPS 1e-8 #define sq sqrt #define S second #define F first #define mod 998244353 using namespace std; char buf[1<<15],*fs,*ft; inline char getc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline int read() { RE int x=0,f=1;RE char ch=getc(); while(ch'9'){if(ch=='-')f=-1;ch=getc();} while(ch>='0'&&ch<='9'){x=((ll)x*10+ch-'0')%mod;ch=getc();} return x*f; } const int MAXN=4010,G=3; int n,k,l,r; ll f[MAXN]; int sum[MAXN],pre[MAXN][MAXN]; int c[MAXN][MAXN],cnt[MAXN]; struct wy{int l,r,x;}q[MAXN]; inline int cost(int i,int j) { return (sum[j]-c[i-1][j]*2+sum[i-1])>>1; } inline int pd(int x,int y,int z) { if(f[x]+cost(x+1,z)>1; if(pd(a.x,x,mid))r=mid; else l=mid+1; } return r; } inline void calc(int x) { q[l=r=1]=(wy){1,n,0}; rep(1,n,i) { while(lr){q[++r]=(wy){i+1,n,i};continue;} int w=calc(q[r],i); q[r].r=w-1;q[++r]=(wy){w,n,i}; } } } int main() { //freopen("1.in","r",stdin); get(n);get(k); rep(1,n,i) { rep(1,n,j) { int get(x); pre[i][j]=pre[i][j-1]+x; c[i][j]=c[i-1][j]+pre[i][j]; } sum[i]=sum[i-1]+(pre[i][i]<<1); } int l=0,r=(sum[n]>>1)+1; while(l+1>1; calc(mid); if(cnt[n]>=k)l=mid; else r=mid; } calc(r); if(cnt[n]>=k)l=r;else calc(l); putl(f[n]-k*l);return 0; }

좋은 웹페이지 즐겨찾기