Solutions of Maximum sum subset - MarisaOJ: Marisa Online Judge

Solutions of Maximum sum subset

Select solution language

Write solution here.


User Avatar sharinganvanhoadong    Created at    1 likes

#**HƯỚNG DẪN:**<br> - Ý tưởng tương tự bài [Chênh lệch nhỏ nhất](https://marisaoj.com/problem/114). Ta vẫn chia đôi tập và sinh tất cả các tổng con của $2$ dãy.<br> - Tuy nhiên vấn đề là có $mod 10^9.$ Ngăn chặn việc tìm tổng lớn nhất đơn thuần (vì lớn hơn $10^9$ là dư lại về $0$).<<br> - Xử lý: Ta rút gọn tối đa giá trị các tổng con (chỉ lấy dư cho $10^9$). Khi đó các giá trị cần ghép lại từ $2$ mảng đều $<10^9.$ Nên $0<=a_1[vt1]+a_2[vt2]<2\*10^9$<br> Với mỗi $a_1[vt1]$ ta có thể chia mảng $a_2$ làm $2$ phần (tổng với $a_1[vt1]$ lớn hơn hoặc nhỏ hơn $10^9$)<br> $+$ Lớn hơn: Lấy phần tử lớn nhất trong đó (tức là phần tử lớn nhất của cả dãy $a_2$)(có thể phần tử lớn nhất đó cộng với $a_1[vt1]$ bé hơn $10^9$ nhưng ta cứ xét hết vì không ảnh hưởng gì(ứng cử viên cho đáp án))<br> $+$ Nhỏ hơn: Lấy phần tử lớn nhất trong đó.<br> $->$ Ta sắp xếp $2$ mảng và dùng thuật toán $2$ con trỏ hoặc tìm kiếm nhị phân để tìm.<br> ##**CODE MẪU:**<br> ```cpp #include<iostream> #include<vector> #include<algorithm> using namespace std; int n; vector<long long> a1,a2; long long inp[41],ans=-1,sum,mod=1e9; void sinhtongcon(int i,int r,long long s,vector<long long> &a) { if(i>r) a.push_back(s%mod); else { sinhtongcon(i+1,r,s,a); sinhtongcon(i+1,r,(s+inp[i])%mod,a); } } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>inp[i]; sinhtongcon(1,n/2,0,a1); sinhtongcon(n/2+1,n,0,a2); sort(a1.begin(),a1.end()); sort(a2.begin(),a2.end()); int vt1=0,n1=a1.size(),vt2=a2.size()-1; int mx=a2[vt2]; while(vt1<n1&&vt2>=0) { if(a1[vt1]+a2[vt2]>=mod) vt2--; else ans=max(ans,max((a1[vt1]+mx)%mod,a1[vt1]+a2[vt2])),vt1++; } cout<<ans; } ```