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;
}