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
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]表示1到i,第i站用了k次的最大值,然后我们只需枚举1到i的点。。。。
然后发现如果我们暴力求每次能多增加多少人会T。。。
然后用前缀和优化一下就好了。。。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 600+5 14 #define maxm 50+5 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<=(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 int tot,rec,cnt,sum[maxn][maxn],a[maxn][maxn],f[maxn][maxm],ans[maxn],pre[maxn][maxn]; 30 int main(){ 31 //freopen("input.txt","r",stdin); 32 //freopen("output.txt","w",stdout); 33 int n=read(),k=read(); 34 for1(i,n-1) 35 for(int j=i+1;j<=n;j++) 36 a[i][j]=read(); 37 for1(i,n){ 38 sum[i][n]=sum[i-1][n]+a[i][n]; 39 for(int j=n-1;j>=1;j--) 40 sum[i][j]=sum[i-1][j]+sum[i][j+1]-sum[i-1][j+1]+a[i][j]; 41 } 42 memset(f,-1,sizeof(f)); 43 f[0][0]=0; 44 for1(i,k) 45 for(int j=i;j<n;j++) 46 for(int t=i-1;t<j;t++) 47 if(f[t][i-1]!=-1) 48 if(f[j][i]<f[t][i-1]+sum[j][j+1]-sum[t][j+1]){ 49 f[j][i]=f[t][i-1]+sum[j][j+1]-sum[t][j+1]; 50 pre[j][i]=t; 51 } 52 for(int i=k;i<=n;i++) 53 if(f[i][k]>tot){ 54 tot=f[i][k]; 55 rec=i; 56 } 57 while(k){ 58 ans[++cnt]=rec; 59 rec=pre[rec][k]; 60 k--; 61 } 62 for(int i=cnt;i>1;i--) 63 printf("%d ",ans[i]); 64 printf("%d\n",ans[1]); 65 return 0; 66 }