USACO FEB08 Problem 'egroup' Analysis
by Christos Tzamos
The problem asked to sort the dining groups in either
nonincreasing or nondecreasing order. Here we will discuss the nondecreasing
order as the other is equivalent.
A simple solution is to iterate
through every possible case, calculate the number of changes required and keep
the minimum of those numbers. The time complexity of this method is O(N^3) which
can be reduced in O(N^2) by either precalculating the number of changes for
every interval of every type or by calculating the number of changes for every
case based on the previous case so that we can calculate the number of changes
in O(1).
However this solution will get you 7-8 test cases but will not
give you full points. The constraint N <= 30,000 asks for a faster method and
that is dynamic programming which gives as a time complexity of O(N).
By
noticing that if we know the minimum number of changes needed up to the cow i-1
so that she has a card a, we can calculate the minimum number of changes needed
up to the cow i so that she has a card of type b. Actually:
if cow i has
card of type l
minchanges[i][b] = min( minchanges[i-1][a] ) for every
a<=b
else
minchanges[i][b] = 1 + min( minchanges[i-1][a] ) for every
a<=b
And then the answer is min( minchanges[N][k] ) for 1<=k<=3
Below is my code:
#include<cstdio>
int A[1000000],N,dp[1000000][3];
int min(int a,int b) {return a<b?a:b;}
int fans() {
dp[0][0]=dp[0][1]=dp[0][2]=1;
dp[0][A[0]-1]=0;
for(int i=1;i<N;i++) {
dp[i][0] = dp[i-1][0]+1-(A[i]==1);
dp[i][1] = min(dp[i-1][0],dp[i-1][1])+1-(A[i]==2);
dp[i][2] = min(min(dp[i-1][0],dp[i-1][1]),dp[i-1][2])+1-(A[i]==3);
}
return min(min(dp[N-1][0],dp[N-1][1]),dp[N-1][2]);
}
int main() {
freopen("egroup.in","r",stdin);
freopen("egroup.out","w",stdout);
scanf("%d",&N);
int i,v;
for(i=0;i<N;i++) scanf("%d",A+i);
v = fans();
for(i=0;i<N;i++) A[i]=4-A[i];
v <?= fans();
printf("%d\n",v);
return 0;
}