[NOIP2015 시뮬레이션 11.2만] 배미표

Description


Alice와 Bob, 아뇨, CZL과 YYY가 게임을 하고 있어요.책상 위에 n장의 카드가 있는데, 한 장의 카드는 두 사람에게 각각 유혹의 가치와 그 자신의 가치를 가지고 있다.CZL이 먼저 매번 조작자가 값 X를 외친 다음에 책상 위에 남은 그의 유혹치 <=X의 카드를 모두 거두어들이고(적어도 한 장) 그 가치를 얻는다.CZL의 최대 득점을 구하다.

Solution


바둑, DP 거꾸로.우선 유혹치를 이산화한다.Fi, j를 설정하면 CZL이 i를 외치고 YYY가 j를 외치면 CZL의 최대 수익을 나타낸다.Gi, j는 YYY의 최대 수익을 나타냅니다.전이 방정식이 뚜렷하다.Fi,j=max(Si,j-Gk,j),k>i 그리고 이 구간에 적어도 한 장의 카드가 있다.G동리.바꾸자,Fi,j=Si,j-min(Gk,j).뒤에 있는 그 물건을 bj로 설정하면 분명히 b는 선형으로 처리할 수 있다.허허

Code

#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define N 1005
#define ll long long
using namespace std;
int a[N],x[N],y[N],data[N],cnt[N][N],n,tot;
ll f[N][N],g[N][N],sum[N][N],F[N],G[N];
void prepare(int *x) {
    fo(i,1,n) data[i]=x[i];
    sort(data+1,data+n+1);
    int m=unique(data+1,data+n+1)-data-1;
    fo(i,1,n) x[i]=lower_bound(data+1,data+m+1,x[i])-data;
}
int main() {
    freopen("poker.in","r",stdin);
    freopen("poker.out","w",stdout);
    scanf("%d",&n);
    fo(i,1,n) scanf("%d",&a[i]);
    fo(i,1,n) scanf("%d%d",&x[i],&y[i]);
    prepare(x);prepare(y);
    fo(i,1,n) sum[x[i]][y[i]]+=(ll)a[i],cnt[x[i]][y[i]]++;
    fd(i,n,1) fd(j,n,1) {
        sum[i][j]=sum[i][j]+sum[i+1][j]+sum[i][j+1]-sum[i+1][j+1];
        cnt[i][j]=cnt[i][j]+cnt[i+1][j]+cnt[i][j+1]-cnt[i+1][j+1];
    }
    fd(i,n,1) fd(j,n,1) {
        if (cnt[i][j]==cnt[i+1][j]) f[i][j]=f[i+1][j];
        else f[i][j]=sum[i][j]-G[j];
        if (cnt[i][j]==cnt[i][j+1]) g[i][j]=g[i][j+1];
        else g[i][j]=sum[i][j]-F[i];
        F[i]=min(F[i],f[i][j]);G[j]=min(G[j],g[i][j]);
    }
    printf("%lld",f[1][1]);
}

좋은 웹페이지 즐겨찾기