zoukankan      html  css  js  c++  java
  • 洛谷P1854 花店橱窗布置

    题目

    DP,直接递推比记忆化搜索简单。

    定义状态(dp[i][j])为前i行最后一个选择第i行第j个数所得到最大值。

    易得状态转移方程

    (dp[i][j]=max(dp[i-1][k]+a[i][j]))

    这个题比较困难的就是在(j)(k)的枚举上。(j)要满足选(j)的时候一定要比(i)大,比((m-(n-i)))小,只有这样才能使前i朵花都可选,后i朵花都可选。而k因为在上一行,所以只需要比j小就好。

    #include <bits/stdc++.h>
    using namespace std;
    const int _INF = -2054847099;
    int n, m, maxn;
    int a[1001][1001]; 
    //dp[i][j]是必须选择第i,j个数的最大值。 
    int dp[1001][1001], pre[1001][1001];
    int main()
    {
     	memset(dp, -123, sizeof(dp));
     	scanf("%d%d", &n, &m);
     	for (int i = 1; i <= n; i++)
     		for (int j = 1; j <= m; j++)
     			scanf("%d", &a[i][j]);
     	for (int i = 1; i <= m; i++)
     		dp[1][i] = a[1][i];
     	for (int i = 2; i <= n; i++)
    		for (int j = i; j <= m - (n - i); j++)
    		{
    			for (int k = 1; k < j; k++)
    			{
    				if (dp[i][j] < dp[i - 1][k] + a[i][j])
    				{
    					dp[i][j] = dp[i - 1][k] + a[i][j];
    					pre[i][j] = k;
    				}
    			}
    		}
    	int maxn = 0, maxk;
    	for (int i = 1; i <= m; i++)
    		if (maxn < dp[n][i])
    		{
    			maxn = dp[n][i];	
    			maxk = i;
    		}
    	printf("%d
    ", maxn); 
    	stack <int> s;
    	s.push(maxk);
    	while (n)
    	{
    		maxk = pre[n--][maxk];
    		s.push(maxk);
    	}
    	s.pop();
    	while (s.size())
    	{
    		printf("%d ", s.top());
    		s.pop();
    	}
     	return 0;
    }
    
  • 相关阅读:
    顺序队列的模板
    链式队列模板
    链式栈模板
    栈应用hanoi
    判断出栈顺序
    用栈实现四则运算
    两栈共享问题
    The Preliminary Contest for ICPC Asia Nanjing 2019
    Educational Codeforces Round 71 (Rated for Div. 2)
    HDU6583:Typewriter(dp+后缀自动机)
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/11749088.html
Copyright © 2011-2022 走看看