CodeForces - 987C___Three displays——动态规划(背包+思维)

题目链接:点我

题目大意:

     n n 个物品,每个物品体积为 s i s_i ,花费为 c i c_i ,每次选 3 3 个物品,使这三个物品 i < j < k i<j<k ,并且 s i < s j < s k s_i<s_j<s_k ,求最小花费???

解题思路:

    明显是dp,问题是怎么dp,在这里给出两种方法,因为要选三个物品,下面一种是特殊的方法,一种是一般的方法:
f [ i , k ] f[i,k] 代表第 i i 个物品作为选出的三个物品中的第 k k 个物品的最小花费,那么只需要遍历一遍 i i ,每次遍历取两个物品,在前i个物品中选取符合要求且花费最小的物品,那么状态转移方程就是: f [ i , k ] = m i n ( f [ j , k 1 ] + c [ i ] ) f[i,k]=min(f[j,k−1]+c[i]) ,其中: j < i j<i s [ j ] < s [ i ] s[j]<s[i]

:因为只需要选三个物品,那么我先遍历一遍i,每次遍历中,找到i之后花费最小的那个物品,这样就选择了二个物品的最优解,记录到这个 d p [ i ] dp[i]
    再次遍历一遍i,每次遍历选择i之前花费最小的那个物品,这样既不会重复,也就选到了三个物品的最优解!

PS:第一种方法可以延伸到任意数量的物品(复杂度允许的话),而第二种方法只能选择三个物品,因为只能遍历两次~

代码思路:

    状态转移: f [ i , k ] = m i n ( f [ j , k 1 ] + c [ i ] ) f[i,k]=min(f[j,k−1]+c[i]) ,其中: j < i j<i s [ j ] < s [ i ] s[j]<s[i]

    时间复杂度: O ( N 2 ) O(N^2)

核心:熟练的使用dp,不行就多练吧弟弟

第一种方法(推荐):

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3007, inf = 0x3f3f3f3f;
int f[maxn][4], n, val[maxn], cost[maxn], ans = inf;

int main() 
{
	scanf("%d", &n);
	for (int i=1; i<=n; i++) scanf("%d", val + i);
	for (int i=1; i<=n; i++) scanf("%d", cost + i);
	memset(f, 0x3f, sizeof(f));
	for (int i=1; i<=n; i++) {
		f[i][1] = cost[i];
		for (int k=2; k<=3; k++)
			for (int j=1; j<i; j++)
				if (val[j] < val[i]) 
					f[i][k] = min(f[i][k], f[j][k - 1] + cost[i]);
	}
	for (int i=1; i<=n; i++) 
		ans = min(ans, f[i][3]);
	printf("%d\n", ans == inf ? -1 : ans);
	return 0;
}

第二种方法(也推荐):

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, dp[3005];
int s[3005], c[3005];

int main()
{
	scanf("%d", &n);
	for(int i=1; i<=n; i++)	scanf("%d", s+i);
	for(int i=1; i<=n; i++)	scanf("%d", c+i);
	for(int i=1; i<=n; i++) dp[i] = INT_MAX;
	for(int i=1; i<=n; i++)
		for(int j=i+1; j<=n; j++)
			if(s[i]<s[j])
				dp[j] = min(dp[j], c[i]+c[j]);
	
	int ans = INT_MAX;
	for(int i=1; i<=n; i++)
		for(int j=i+1; j<=n; j++)
			if(s[i]<s[j] && dp[i]!=INT_MAX)
				ans = min(ans, dp[i]+c[j]);
	
	if(ans == INT_MAX) printf("-1");
	else printf("%d", ans);
}

猜你喜欢

转载自blog.csdn.net/Scar_Halo/article/details/83062859
今日推荐