每日算法 - day 49

每日算法

those times when you get up early and you work hard; those times when you stay up late and you work hard; those times when don’t feel like working — you’re too tired, you don’t want to push yourself — but you do it anyway. That is actually the dream. That’s the dream. It’s not the destination, it’s the journey. And if you guys can understand that, what you’ll see happen is that you won’t accomplish your dreams, your dreams won’t come true, something greater will. mamba out


那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~

2020.4.4


简单的烦恼

将问题抽象为01背包问题
贪心 + dp
为了获取尽可能长的时间我们对数据进行排序只获取前 n-1首歌在 t-1时间内能听的最长时间
最后一分钟开始播放最长的那一首歌获取最大播放时间
t : 背包容量
n :物品个数
w[i] : a[i] v[i] : w[i]
注意所给定的w[i]一定要按照从小到大的顺序排列

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>

using namespace std;
const int N = 2005;
const int M = 80005;
int f[M] ,a[N] , n , m;
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		cin >> n >> m;
		for(int i = 1;i <= n ;i ++)cin >> a[i];
		sort(a + 1, a + 1 + n);
		for(int i = 1;i <= n - 1;i ++)
		{
			for(int j = m - 1; j >= a[i] ;j --)
			{
				f[j] = max(f[j],f[j-a[i]] + a[i]);
			}
		}
		cout << f[m-1] + a[n]<< endl;
		fill(f , f + m , 0);
	}
	return 0;
}

P1507 NASA的食物计划

01背包扩展 多为01 背包即权重属性扩充至多维相应的f数组应该改开至相应的维度

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;
const int N = 405;
int a[N],b[N],c[N],f[N][N];
int n , m , t;

// 01背包扩展   多维01背包
int main()
{
	cin >> n >> m;
	cin >> t;
	for(int i = 1;i <= t ;i ++)
	{
		cin >> a[i] >> b[i] >> c[i];
	}
    // 有几重
	for(int i = 1;i <= t;i ++)
	{
		for(int j = n; j >= a[i];j--) // 质量最大
			for(int k = m; k >= b[i]; k--)  // 体积
				f[j][k] = max(f[j][k],f[j-a[i]][k-b[i]] + c[i]);
	}
	cout << f[n][m] << endl;
	return 0;
}

货币系统

  1. 另外一个集合一定是给定集合的子集
  2. 另外一个集合可以去除给定集合中可以用集合中的元素表达出来的数字

如果存在大于19(对其他货币系统里的面值也适用)的数X不能被表示,
那么X-19=Y也不能被表示,如果Y大于19,继续以上步骤,直到Y'< 19 不能被表示,与已知矛盾,
故有 f[j] += f[j - a[i]]

给定一个数组求数组中所有的数字可以组成的不超过max(a[i])的数 1 <= i <= n
f[0] = 1;
for(int i = 1;i <= n ;i ++)
{
for(int j = a[i]; j<= a[n]; j++)
{
f[j] += f[j - a[i]];
}
}

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
const int N =  105;
int  t = 0 , n;
int a[N] , f[50005];
int main()
{

	cin >> t;
	while(t--)
	{
		memset(a , 0 ,sizeof a);
		memset(f , 0 ,sizeof f);

		cin >> n;
		int ans = n;
		for(int i = 1;i <= n ;i ++)
		{
			cin >> a[i];
		}
		sort(a + 1, a + 1 + n);
		f[0] = 1;
		for(int i = 1;i <= n ;i ++)
		{
			if(f[a[i]])
			{
				ans--;
				continue;
			}
			for(int j = a[i];j <= a[n]; j++)
			{
				f[j] += f[j - a[i]];
			}
		}
		cout << ans << endl;
	}
	return 0;
}


猜你喜欢

转载自www.cnblogs.com/wlw-x/p/12635078.html