2022-02-22每日刷题打卡

199 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

2022-02-22每日刷题打卡

一本通——动态规划

1268:【例9.12】完全背包问题

【题目描述】

设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。

【输入】

第一行:两个整数,MM(背包容量,M≤200)和NN(物品数量,N≤30N≤30);

第2…N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

【输出】

仅一行,一个数,表示最大总价值。

【输入样例】

10 4 
2 1 
3 3
4 5 
7 9
【输出样例】
max=12

这里因为物品数量较小,可以用01背包的写法,每个货物一直拿拿到背包装不下位置,其它和01背包一样。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>

typedef long long ll;
const int N = 210;
ll f[N], v[N], w[N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
		cin >> v[i] >> w[i];
	for (int i = 0; i < m; i++)
	{
		for (int j = n; j >= 0; j--)
		{
			for (int k = 1; k * v[i] <= j; k++)
			{
				f[j] = max(f[j], f[j - k * v[i]] + k * w[i]);
			}
		}
	}
	cout << "max=" << f[n] << endl;

	return 0;
}

如果数值太大就要换一个方法,01背包运算时枚举背包空间是从大到小,完全背包是从小到大。这样在运算枚举后面更大的背包时,可以借助之前算好的小的背包更快的算出结果

#include<iostream>
using namespace std;

const int N=1010;
int f[N],w[N],v[N];
int n,m;

int main()
{
    cin>>m>>n;
    for(int i=0;i<n;i++)cin>>v[i]>>w[i];
    for(int i=0;i<n;i++)
        for(int j=v[i];j<=m;j++)
            f[j]=max(f[j],f[j-v[i]]+w[i]);
    cout<<"max="<<f[m]<<endl;
    return 0;
}

1270:【例9.14】混合背包

【题目描述】

一个旅行者有一个最多能装V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,…,Wn,它们的价值分别为C1,C2,…,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

【输入】

第一行:二个整数,M(背包容量,M<=200),N(物品数量,N<=30);

第2…N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(Pi)。

【输出】

仅一行,一个数,表示最大总价值。

【输入样例】

10 3 2 1 0 3 3 1 4 5 4

【输出样例】

11

【提示】

选第一件物品1件和第三件物品2件。

和上一题的完全背包很像,只不过这里出现了一个购买数量为无限的存在,只要多一个判断判断s[i]=0时可以无线拿即可。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>

typedef long long ll;
const int N = 10010;
ll f[N], v[N], w[N], s[N];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
		cin >> v[i] >> w[i] >> s[i];
	for (int i = 0; i < m; i++)
	{
		for (int j = n; j >= 0; j--)
		{
			for (int k = 1; k * v[i] <= j && ((s[i] != 0 && k <= s[i])||!s[i]); k++)
			{
				f[j] = max(f[j], f[j - k * v[i]] + k * w[i]);
			}
		}
	}
	cout << f[n] << endl;

	return 0;
}

蓝桥杯——历届真题

历届真题 时间显示【第十二届】【省赛】【B组】

在这里插入图片描述

#include<iostream>
using namespace std;
#include<string>

typedef long long ll;

string get_string(ll num)
{
	if (num == 0)return "0";
	string str;
	while (num)
	{
		int a = num % 10;
		num /= 10;
		str += a + '0';
	}
	reverse(str.begin(), str.end());
	return str;
}

int main()
{
	string str;
	long long time;
	cin >> time;
	time /= 1000;
	time -= (time / 86400) * 86400;
	int hour = time / 3600;
	if (hour < 10)str += "0";
	str += get_string(hour);
	str += ":";
	time -= (time / 3600) * 3600;
	int mintue = time / 60;
	if (mintue < 10)str += "0";
	str += get_string(mintue);
	str += ":";
	time -= (time / 60) * 60;
	if (time < 10)str += "0";
	str += get_string(time);
	cout << str;
	return 0;
}