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