1002 Business (35 分)
解题思路:
N<=50,P,L,D未知,暴力搜索2^50会T一个点,尝试记忆化搜索(数据范围未知所以不确定),用vis记录<i,now,ans>i为当前dfs的位置,now为当前的时间,ans为当前的答案,用if (vis[i][now][ans])return;来实现记忆化搜索,减少搜索复杂度。
坑点:
若破坏某个城市后网络不连通,则该城市的代价为最大(如果有多个这样的城市,则输出多个)
代码:
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define mp make_pair
#define pb push_back
#define G 6.67430*1e-11
#define rd read()
#define pi 3.1415926535
using namespace std;
const ll mod = 998244353;
const int MAX1 = 100005;
const int MAX2 = 300005;
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
ll gcd(ll a, ll b) { return !b ? a : gcd(b, a % b); }
struct ss
{
int num, time, ddl, flag;
}x[55];
int n;
int a = 0;
map<int,map<int,map<int,int>>> vis;
void dfs(int i, int now, int ans)
{
if (i >= n)
{
//cout << ans << endl;
a = max(a, ans);
return;
}
if (vis[i][now][ans])return;
vis[i][now][ans] = 1;
if (now + x[i].time > x[i].ddl || !x[i].flag)return dfs(i + 1, now, ans);
else
{
dfs(i + 1, now + x[i].time, ans + x[i].num);
dfs(i + 1, now, ans);
}
}
bool cmp(ss a, ss b)
{
return a.ddl < b.ddl||(a.ddl==b.ddl&&a.time<b.time);
}
signed main()
{
n = rd;
for (int i = 0; i < n; i++)
{
x[i].num = rd;
x[i].time = rd;
x[i].ddl = rd;
x[i].flag = 1;
}
sort(x, x + n, cmp);
for (int i = 1; i < n; i++)
{
if (x[i].ddl == x[i - 1].ddl && x[i].time == x[i - 1].time)
{
int ma = x[i - 1].num;
int j = i;
while (x[i].ddl == x[i - 1].ddl && x[i].time == x[i - 1].time)
{
x[i].flag = 0;
ma = max(x[i].num, ma);
i++;
}
x[j - 1].num = ma;
}
}
//for (int i = 0; i < n; i++)
//{
// cout << x[i].num << ' ' << x[i].time << ' ' << x[i].ddl << ' ' << x[i].flag << endl;
//}
dfs(0, 0, 0);
cout << a;
return 0;
}