10690  Expression Again
Moderator: Board moderators
10690
To maximize the expression, I think I should divide the numbers into two parts and make their difference minimum. But how to do it? Some one says DP. But I still have no idea how to DP. Who can give more hints.
I stay home. Don't call me out.
 Martin Macko
 A great helper
 Posts: 481
 Joined: Sun Jun 19, 2005 1:18 am
 Location: European Union (Slovak Republic)
Re: How to solve 10690?
There is already a thread on this problem. If there is a thread on a particular problem, please, use it to post your question and do not create a new one. (see http://onlinejudge.uva.es/board/viewtopic.php?t=6213 and http://onlinejudge.uva.es/board/viewtopic.php?t=6233)
forum 'Volume CVI' description wrote:All about problems in Volume CVI. If there is a thread about your problem, please use it. If not, create one with its number in the subject.
How to DP? Could you tell it more detailedly? I've solved 10664, but keep getting TLE on 10690. Let me describe my algorithm:
And I used an optimizing: in the second loop, the count number c is never greater than the count of x in the problem description (Or the count of y, use the lower one).
Can you give me more idea to optimize my algorithm? Or my algorithm is totally wrong?
Code: Select all
Use an array of set, named "reach". reach[i] stores the sums that can be reached by i numbers.
for every number n {
for every count of number c (from greater to lower) {
With the set reach[c] and the number n, I can add more sums to the set reach[c + 1].
}
}
Can you give me more idea to optimize my algorithm? Or my algorithm is totally wrong?
I stay home. Don't call me out.
Re: 10690  Expression Again
Hi, I got time limit exceeded for this problem. Please tell me how to improve solution. I used dp subset sum.
Code: Select all
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int _min,_max;
int dp[110][110][5500];
int N,M,a[110];
int mi,totalsum;
void ExpAgain(int idx,int num,int sum){
if(num==mi){
_min=min(_min,sum*(totalsumsum));
_max=max(_max,sum*(totalsumsum));
return;
}
if(idx>=(N+M)) return;
if(dp[idx][num][sum+2600]!=1) return;
dp[idx][num][sum+2600]=1;
ExpAgain(idx+1,num+1,sum+a[idx]);
ExpAgain(idx+1,num,sum);
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d %d",&N,&M)!=EOF){
totalsum=0;
for(int i=0;i<(N+M);i++){
scanf("%d",&a[i]);
totalsum+=a[i];
}
mi=min(N,M);
_max=0;
_min=2000000000;
memset(dp,1,sizeof dp);
ExpAgain(0,0,0);
printf("%d %d\n",_max,_min);
}
}

 Guru
 Posts: 5947
 Joined: Thu Sep 01, 2011 9:09 am
 Location: San Jose, CA, USA
Re: 10690  Expression Again
My approach, AC in 1.156 seconds.
You need to divide the numbers into two groups, so find all the possible sums of min(N, M) of the integers. The sum of the remaining integers is easy to find.
I use a hash: unordered_set<int> to store all possible sums of each number of integers.
Iterate through each of the N + M integers, and then iterate through each of the numbers of integers, and add the current integer to each of the possible sums.
You need to divide the numbers into two groups, so find all the possible sums of min(N, M) of the integers. The sum of the remaining integers is easy to find.
I use a hash: unordered_set<int> to store all possible sums of each number of integers.
Iterate through each of the N + M integers, and then iterate through each of the numbers of integers, and add the current integer to each of the possible sums.
Check input and AC output for thousands of problems on uDebug!

 Experienced poster
 Posts: 117
 Joined: Wed May 18, 2011 3:04 pm
Re: 10690  Expression Again
Test data generator.
Code: Select all
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(int argc, char *argv[])
{
srand(time(NULL));
int number[101];
for (int i = 1; i <= 110; i++)
{
int N = rand() % 50; N++;
int M = rand() % 50; M++;
int T = (N + M);
cout << N << ' ' << M << '\n';
for (int j = 1; j <= T; j++)
{
int K = rand() % 101; K = 50;
number[j] = K;
}
cout << number[1];
for (int j = 2; j <= T; j++)
cout << ' ' << number[j];
cout << '\n';
}
return 0;
}
My solutions for UVa problems: https://github.com/metaphysis/Code.