曾经遇到过类似的。纪念一下!这题同一时候也是 ZOJ1877。经典的过桥问题 是有个博客解说的非常好的
挺久曾经。遇到过一个基本一样的,那个题目仅仅要求求出 最短时间就可以,如今还有过桥的过程 也要输出来,一样的
近期也遇到过一个 类似的过河的,只是题意类似,是DP的, 记得是 CF295C
还记得当初做那道题目 钻入牛角,首先1个人2个人3个人肯定不用说了,当人数大于4的时候,那时候 我想出的贪心策略是 最快的 带最慢的过去。然后回来。再带最慢的过去。当时WA到死。那题案例出的也好。后来发现 事实上另一种贪心策略在某种情况下 比这个好,就是 最快 次快的过去,然后最快的回来。然后最慢次慢的过去,然后次快的再回来。这两个情况没有绝对的谁优。所以 每次都比較一下。这样题目就简单多了,草稿纸一些 两种方法的计算方式就出来了
如果最快a,次快b。次慢c,最慢d
那么 第一种 d + a + c + a
另外一种 b + a + d + b
非常快就做出来了
int n; int nnum[1000 + 55]; void init() { memset(nnum,0,sizeof(nnum)); } bool input() { while(cin>>n) { for(int i=0;i<n;i++)cin>>nnum[i]; return false; } return true; } void solve() { } void cal() { sort(nnum,nnum + n); if(n == 1) { cout<<nnum[0]<<endl; cout<<nnum[0]<<endl; return ; } int pos = n - 1; int ans = 0; while(true) { if(pos <= 2)break; ans += min(nnum[0] * 2 + nnum[pos] + nnum[pos - 1],nnum[1] * 2 + nnum[0] + nnum[pos]); pos -= 2; } if(pos == 2)ans += nnum[0] + nnum[1] + nnum[2]; else ans += nnum[1]; cout<<ans<<endl; pos = n - 1; while(true) { if(pos <= 2)break; if(nnum[0] * 2 + nnum[pos] + nnum[pos - 1] < nnum[1] * 2 + nnum[0] + nnum[pos]) { cout<<nnum[0]<<" "<<nnum[pos]<<endl; cout<<nnum[0]<<endl; cout<<nnum[0]<<" "<<nnum[pos - 1]<<endl; cout<<nnum[0]<<endl; } else { cout<<nnum[0]<<" "<<nnum[1]<<endl; cout<<nnum[0]<<endl; cout<<nnum[pos - 1]<<" "<<nnum[pos]<<endl; cout<<nnum[1]<<endl; } pos -= 2; } if(pos == 2) { cout<<nnum[0]<<" "<<nnum[2]<<endl; cout<<nnum[0]<<endl; cout<<nnum[0]<<" "<<nnum[1]<<endl; } else cout<<nnum[0]<<" "<<nnum[1]<<endl; } void output() { } int main() { while(true) { init(); if(input())return 0; cal(); output(); } return 0; }