SGU 104 – Classical DP Problem

/* Classic DP Problem, first appear in my high school.
 * dp[i][j] represent the max value to put flower i in vase j.
 * dp[i][j] = max(dp[i-1][k]) + a[i][j] (i-1 <= k < j)
 * the value dp[i-1][k] can be used and reduce one for loop, i.e for(int k=i-1;k<j;k++)
 * put[i][j] represent the vase id of flower i-1 put.
 */
#include<cstdio>
#include<cstring>
 
int F,V;
int a[105][105];	//appear value
int dp[105][105];
int put[105][105];
 
void print_order(int i, int j)
{
	if(i==0) return;
	print_order(i-1,put[i][j]);
	printf("%d",j);
	if(i==F) putchar('\n'); else putchar(' ');
}
 
int main()
{
	while(scanf("%d %d",&F,&V)!=EOF)
	{
		for(int i=1;i<=F;i++)
			for(int j=1;j<=V;j++)
				scanf("%d",&a[i][j]);
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=F;i++)
		{
			int k=i-1,tmp=-(1<<29),p;
			for(int j=i;j<=V;j++)
			{
				while(k<j) {					
					if(tmp<dp[i-1][k]) p=k,tmp=dp[i-1][k];
					k++;
				}
				dp[i][j]=dp[i-1][p]+a[i][j];
				put[i][j]=p;
			}
		}
		int ans=-(1<<29),p;
		for(int j=F;j<=V;j++)
			if(dp[F][j]>ans) p=j,ans=dp[F][j];
		printf("%d\n",ans);
		print_order(F,p);
	}
	return 0;
}

Leave a Reply

Your email address will not be published.