zoukankan      html  css  js  c++  java
  • [POI2009]KON-Ticket Inspector(二维前缀和+DP)

    题意

    有n个车站,现在有一辆火车从1到n驶过,给出aij代表从i站上车j站下车的人的个数。列车行驶过程中你有K次检票机会,所有当前在车上的人会被检票,问最多能检多少个不同的人的票

    (n<=600,k<=50)

    题解

    一开始没啥思路,然后瞄了一眼题解。看到了前缀和然后就想前缀和的意义。

    结果又没什么收获。绝望之际想到我瞄的那一眼,看到矩阵是倒着的,然后就有了思路。

    DP也就轻而易举地想出来了。

    我们建立以左上为原点的前缀和。

    然后sum[i][i+1]表示的就是经过i号站点的人数。

    然后dp[i][j]代表前i个车站以第i个车站为第j个选择的车站的最优解。

    方程:

    dp[i][j]=max(dp[i][j],dp[x][j-1]+sum[i][i+1]-sum[x][i+1])(0<=x<i)

    然后记录dp[i][j]从哪里转移就可以得到答案了。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=700;
     8 int n,k,a[N][N],sum[N][N],dp[N][60],ans,num,ans1,ans2[70],from[N][60];
     9 int main(){
    10     scanf("%d%d",&n,&k);
    11     num=k;
    12     for(int i=1;i<=n;i++){
    13         for(int j=1;j<=n-i;j++){
    14             scanf("%d",&a[i][j+i]);
    15         }
    16     }
    17 //    for(int i=1;i<=n;i++){
    18 //        for(int j=1;j<=n;j++){
    19 //            cout<<a[i][j]<<" ";
    20 //        }
    21 //        cout<<endl;
    22 //    }
    23     for(int i=1;i<=n;i++){
    24         for(int j=n;j>=1;j--){
    25             sum[i][j]=sum[i-1][j]+sum[i][j+1]-sum[i-1][j+1]+a[i][j];
    26         }
    27     }
    28 //    for(int i=1;i<=n;i++){
    29 //        for(int j=1;j<=n;j++){
    30 //            cout<<sum[i][j]<<" ";
    31 //        }
    32 //        cout<<endl;
    33 //    }
    34     for(int i=0;i<=n;i++)
    35         for(int j=0;j<=k;j++){
    36             dp[i][j]=-99999999;
    37         }
    38     dp[0][0]=0;
    39     for(int i=1;i<=n;i++)
    40         for(int j=1;j<=min(i,k);j++)
    41             for(int x=0;x<i;x++){
    42                 if(dp[i][j]<dp[x][j-1]+sum[i][i+1]-sum[x][i+1]){
    43                     dp[i][j]=dp[x][j-1]+sum[i][i+1]-sum[x][i+1];
    44                     from[i][j]=x;
    45                 }
    46             }
    47     for(int i=k;i<=n-1;i++){
    48         if(ans<dp[i][k]){
    49             ans1=i;
    50             ans=dp[i][k];
    51         }
    52     }
    53 //    cout<<ans<<endl;
    54     while(ans1){
    55         ans2[num]=ans1;
    56         ans1=from[ans1][num];
    57         num--; 
    58     }
    59     for(int i=1;i<=k;i++){
    60         printf("%d ",ans2[i]);
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    Sublime Text前端开发环境配置
    CSS盒模型
    Angular-如何在Angular2中使用jQuery及其插件
    六:Angular 指令 (Directives)
    五:Angular 数据绑定 (Data Binding)
    四:Angular 元数据 (Metadata)
    三:Angular 模板 (Templates)
    二:Angular 组件 (Components)
    一:Angular 模块 (Modules)
    js获取浏览器内核
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9432667.html
Copyright © 2011-2022 走看看