知识点:
1.贪心算法
2.前缀和
问题:
求连续去餐厅最多可以去几天,且第i%7天与i天选在菜得是一样的
(一开始我也没有想到是连续的,还想暴力枚举但是发现复杂度很高,也不好枚举)
算法基本思想:
我们只要关心最新的一天能吃到且价格最低就行
一.第i天去餐厅,
1.如果i<=7,选最价格最低的菜
2.不然,需要去看当前菜(i%7)--(i-7*k)--(i-7)的总价最小,简单的说就是选这个菜,还要考虑以前和现在选的总价(价格之和最低)
二.选完后可以用我们的钱减去新的花费
如果减完后小于0说明这一天不能吃了
大于等于0,说明还可以明天可能还可以吃(如果明天免费0还是可以吃的)
代码实现:
#include<iostream>
#include<algorithm>
#include<vector>
#include<math.h>
#include<cfloat>
#include<set>
#include<unordered_map>
using namespace std;
void solve() {
int n, m, budget;
cin >> n >> m >> budget;
vector<vector<int>> price(n,vector<int>(m,0));
for (int i = 0; i < n; i++) {
string s;
cin >> s;
for (int j = 0; j < m; j++) {
price[i][j] = s[j];
if (s[j] >= '0' && s[j] <= '9') price[i][j] = s[j] - '0';
else if (s[j] >= 'A' && s[j] <= 'Z') price[i][j] = s[j] - 'A'+10;
else price[i][j] = s[j] - 'a'+36;
}
}
vector<int> recoed(7,0);
for (int i = 0; i < n; i++)
{
int spend = 0;
//小于7天直接选最小
if (i < 7) {
for (int j = 0; j < m; j++)
if (price[i][j] < price[i][recoed[i]]) recoed[i] = j;
spend = price[i][recoed[i]];
}
else {
//求前缀和
for (int j = 0; j < m; j++)
price[i][j]+=price[i-7][j];
// 选出最小花费的一道菜
int old = recoed[i % 7];
for (int j = 0; j < m; j++) {
if (price[i][j] < price[i][recoed[i % 7]] ) recoed[i % 7] = j;
}
spend = price[i][recoed[i % 7]] - price[i-7][old];
}
budget -= spend;
if (budget < 0) {
cout << i;
return;
}
}
cout << n;
}
int main() {
std::ios::sync_with_stdio(false); std::cin.tie(0);
solve();
return 0;
}
看完可以点赞一下,相互帮助提升算法能力

京公网安备 11010502036488号