BZOJ 1133 [POI2009]Kon DP
2015-09-17 20:45
441 查看
题意:链接略
方法: DP
解析:
首先DP式子很容易写出来。
设f[i][j]表示前i站查了j次票,并且第i站后要查的最大人数。
f[i][j]=max(f[k][j-1]+peo[x][y])(k<i&&k<=x<i,y>=i)f[i][j]=max(f[k][j-1]+peo[x][y])(k=i)
这样如果我们枚举x,y的话很可能达到O(n^4)左右的复杂度。
所以考虑优化这个部分。
设sum[i][j]=\sum{peo[x][y]}&&x<=i,i<y<=jsum[i][j]=\sum{peo[x][y]}&&x<=i,i
于是f[i][l]=min(f[j][l−1]+sum[i][i+1]−sum[j][i+1])f[i][l]=min(f[j][l-1]+sum[i][i+1]-sum[j][i+1])
注意sum的更新。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 610 #define K 55 using namespace std; int n,k; int sum ; int peo ; int pre [K]; int f [K]; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) scanf("%d",&peo[i][j]); for(int i=1;i<=n;i++) { sum[i] =sum[i-1] +peo[i] ; for(int j=n-1;j>=1;j--) { sum[i][j]=sum[i-1][j]+sum[i][j+1]-sum[i-1][j+1]+peo[i][j]; } } memset(f,-1,sizeof(f)); f[0][0]=0; for(int l=1;l<=k;l++) { for(int i=l;i<n;i++) { for(int j=l-1;j<=i-1;j++) { if(f[j][l-1]!=-1) { if(f[j][l-1]+sum[i][i+1]-sum[j][i+1]>f[i][l]) { f[i][l]=f[j][l-1]+sum[i][i+1]-sum[j][i+1]; pre[i][l]=j; } } } } } int ma=0,no; for(int i=k;i<n;i++) if(f[i][k]>ma) ma=f[i][k],no=i; int ans ; int cnt=0; while(k) { ans[++cnt]=no; no=pre[no][k]; k--; } for(int i=cnt;i>=2;i--)printf("%d ",ans[i]); printf("%d\n",ans[1]); }
相关文章推荐
- 有意练习--Rails RESTful(一)
- Linux 内核的测试和调试
- JS插件之——bootstrap-suggest.js
- 中国剩余定理
- Python的assert
- ios 爱行华夏 技术支持
- 单向电表模块焊接完成
- android 使用activity自定义下拉选择列表
- Nutch第一次搭建部署总结
- 编写一个程序,检查是否一个给定的数字是一个特殊的号码(定义数组版)
- 中国剩余定理
- easyUI之window
- String类的一些方法
- 9.17异常处理
- test4.2
- hdu1074Doing Homework(状态压缩,好题)
- 打开系统相册/相机,选择图片
- jQuery源码学习 之 立即调用 ---- day2
- Redis学习11之jedis问题之1--connect time out
- 获得android手机中的传感器信息