• [POI2009]Kon


    Description
    火车沿途有N个车站,告诉你从每一站到每一站的人数,现在查票员只能查K次票,每次查票可以控制目前在车上的所有乘客的车票。求一个查票方案,使得控制的不同的乘客尽量多。 (显然对同一个乘客查票多次是没有意义的,只算一次)

    Input
    第一行正整数 N K (1≤K<N≤600, K≤50). 接下来N-1行,第i行第j个数描述第i站上,到第i+j站下的乘客个数。总乘客数≤2*10^9

    Output
    单调增的K个整数,用空格隔开,表示经过哪些站以后查票。

    Sample Input
    7 2
    2 1 8 2 1 0
    3 5 1 0 1
    3 1 2 2
    3 5 6
    3 2
    1

    Sample Output
    2 5


    本题dp题,设f[i][k]表示到第i个车站检票k次所控制的人数,因为每次检票到下一次检票相当于检查了一个矩阵内的人数,所以可以据此转移。

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        for (;ch<'0'||ch>'9';ch=getchar())    if (ch=='-')    f=-1;
        for (;ch>='0'&&ch<='9';ch=getchar())  x=(x<<1)+(x<<3)+ch-'0';
        return x*f;
    }
    inline void print(int x){
        if (x>=10)     print(x/10);
        putchar(x%10+'0');
    }
    const int N=6e2,M=50;
    int A[N+10][N+10],sum[N+10][N+10],f[N+10][M+10],pre[N+10][M+10],stack[M+10];
    int main(){
        int n=read(),K=read(),Ans=-inf,ID=0;
        for (int i=1;i<n;i++)    for (int j=i+1;j<=n;j++) A[i][j]=read();
        for (int i=1;i<=n;i++)   for (int j=1;j<=n;j++)   sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+A[i][j];
        memset(f,128,sizeof(f));
        f[0][0]=0;
        for (int i=1;i<=n;i++){
            for (int k=1;k<=K;k++){
                for (int l=0;l<i;l++){
                    int tmp=sum[i][n]-sum[i][i]-sum[l][n]+sum[l][i];
                    if (f[i][k]<f[l][k-1]+tmp){
                        f[i][k]=f[l][k-1]+tmp;
                        pre[i][k]=l;
                    }
                    if (k==K&&Ans<f[i][k]){
                        Ans=f[i][k];
                        ID=i;
                    }
                }
            }
        }
        for (int i=ID,k=K;i;i=pre[i][k--])  stack[k]=i;
        for (int i=1;i<=K;i++)   printf("%d",stack[i]),i!=K?putchar(' '):putchar('
    ');
        return 0;
    }
    
  • 相关阅读:
    分享:两个栈实现一个队列的功能
    分享:要关注技术,但也要关注所做的事情
    linux网络编程中阻塞和非阻塞socket的区别
    分享:C++参数传递方式
    linux非阻塞socket教程
    有用和有趣的产品秤砣
    查找 grep r TFramedTransport *
    分享:SecureCRT使用VIM语法高亮
    linux 非阻塞 socket Google 搜索
    linux c语言 select函数用法 ITeye技术网站
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9118988.html
Copyright © 2020-2023  润新知