Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

二分得到最优值后输出方案确定方法:

Posted by _paul_zhou at 2017-09-24 14:24:59 on Problem 1505
从后向前划分原来的数列,划分时在保证每一块的和不超过最优值的情况下包含尽可能多的项。 这时划分得到的块数可能少于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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator