| ||||||||||
| 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 | |||||||||
二分得到最优值后输出方案确定方法:从后向前划分原来的数列,划分时在保证每一块的和不超过最优值的情况下包含尽可能多的项。 这时划分得到的块数可能少于m块,这时再按照从前向后的顺序划分每一块,在划分出来的总块数不够m块的情况下将前面的每一块打到最散的情况(只含有一项),然后就可以了。
//----------------------------oj测试通过代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <bitset>
#include <vector>
#include <sstream>
#include <assert.h>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
#define fori(i,l,u) for(ll (i)=(ll)(l);(i)<=(ll)(u);++(i))
#define ford(i,l,u) for(ll (i)=(ll)(l);(i)>=(ll)(u);--(i))
#define fir first
#define sec second
const ll inf=0x3fff3fff3fff3fffll;
ll n,m;
const ll maxn=500+10;
ll a[maxn];
bool has_s[maxn];
bool check(ll x){
ll cnt=1,t=0;
fori(i,1,n){
if(t+a[i]<=x) {
t+=a[i];
} else {
cnt++;
t=a[i];
if(a[i]>x) return false;
}
}
return cnt<=m;
}
void solve(){
ll lo=0,hi=5e9+10,ret;
while(lo<=hi){
ll mid=(lo+hi)/2;
if(check(mid)){
hi=mid-1;
ret=mid;
} else {
lo=mid+1;
}
}
// cout<<"ret: "<<ret<<endl;
if(m==1){
fori(i,1,n) {
cout<<a[i];
if(i==n) cout<<endl;
else cout<<" ";
}
} else {
ll t=0;
memset(has_s,false,sizeof(has_s));
ll cnt=0;
ford(i,n,1){
if(t+a[i]>ret){
cnt++;
has_s[i+1]=true;
t=a[i];
} else {
t+=a[i];
}
}
cnt=m-1-cnt;
fori(i,2,n){
if(!has_s[i]&&cnt>0){
has_s[i]=true;
cnt--;
}
}
fori(i,1,n){
if(has_s[i]) cout<<"/ ";
cout<<a[i];
if(i==n) cout<<endl;
else cout<<" ";
}
}
}
int main()
{
ios::sync_with_stdio(false);
// freopen("local.in","r",stdin);
ll T;
while(cin>>T){
while(T--){
cin>>n>>m;
fori(i,1,n) cin>>a[i];
solve();
}
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator