Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
阴险题,63ms的dp,有一点很坑。。。首先看题第一反应肯定是DP的。。。然后关键是得到最小值之后回溯答案不能按照dp的时候记录的来。。。(其实我的代妈中间trc那个数组是废的),比如下面这个数据: 23333 2333 233 233 2333 答案应该是23333/2333/233,233,2333而不是直接dp回溯得到的23333/2333,233/233,2333 因为有了23333之后后面的部分最大值是2333+233还是2333+2*233已经不重要了。。。一句话就是,DP得到的结果,只能保证正确的极值,不一定是正确组合。。。 #include <iostream> #include <stdio.h> using namespace std; int mx[505][505], trc[505][505], psum[505], page[505]; int m,k; int MX(int a, int b){ return (a>b)?a:b; } int MN(int a, int b){ return (a<b)?a:b; } int main() { int n; scanf("%d",&n); for(int ii = 0; ii < n; ii++){ scanf("%d%d",&m,&k); for(int i = 1; i <= m; i++){ scanf("%d", &page[i]); } psum[0] = 0; for(int i = 1; i <= m; i++){ psum[i] = psum[i-1] + page[i]; } mx[m][0] = 0; for(int i = m-1; i >= 0; i--){ int jstart = MX(k-i,1), jend = MN(m-i,k); for(int j = jstart; j <= jend; j++){ int arg = -1, mn = 2147483647; int tstart = MX(k-j+1,i+1), tend = MN(m,m-j+1); if(j == 1) tstart = tend; for(int t = tstart; t <= tend; t++){ if(psum[t]-psum[i] >= mn) break; int thisMn = MX(psum[t]-psum[i], mx[t][j-1]); if(thisMn < mn){ mn = thisMn; arg = t; } } mx[i][j] = mn; trc[i][j] = arg; } } int ren = k, val = mx[0][k], pos = 0; while(ren > 0){ int sstart = pos+1, send = m-ren+1; if(ren==1) sstart = send; for(int s = sstart; s <= send; s++){ if(mx[s][ren-1] <= val){ for(int q = pos; q < s; q++){ printf("%d ", page[q+1]); } if(ren != 1) printf("/ "); pos = s; ren--; break; } } } printf("\n"); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator