//想在这里整理一下思路,刚在做时乱乱的:(导致浪费了很多时间:(
意:给定n组满减优惠,满a减b,m为手上有的钱。求能买的最贵值为多少
//贪心,前缀和
思路:每次个相同的a可能会有不同的b(加到一起);某个a一定包含比它小的a的优惠:sort后求前缀和;小到大枚举叠加的优惠b:m+sum_b>=对应的a,才能有优惠;
(m+sum_b>=a:m>=a-sum_b)
void solve()
{
cin >> n >> m;
map<int, int>mp, sum;
for (int i = 1; i <= n; i++)
{
int a, b;
cin >> a >> b;
sum[a] += b;
}
int k = 0;
for (auto x : sum)
{
int val = x.first, su = x.second;
s[++k] = su;
mp[k] = val;
}
for (int i = 1; i <= k; i++)
s[i] += s[i - 1];
int ans = m;
for (int i = 1; i <= k; i++)
if (s[i] + m >= mp[i])ans = s[i] + m;
cout << ans << endl;
}
//被骗了,看数据范围考察搜索
意:给定一个数组(原先每个编号的得分)m组x号与y号的对战,每次对战有三种结果:a[x]+=3;a[y]+=3;a[x]++,a[y]++;
dfs每种情况即可
O(100*3^10*10)//T*m*n(在n中找到a[1]的排位)
//剪枝:遇到有1的对战直接a[1]+=3,无1的才参与dfs;顺序搜索(搜的顺序对结果无影响;
//稍微看了别人的代码总结的T-T...🥦
const int N = 15;
int n, m, mi, k = 0;
int a[N], x[N], y[N], v[N];
void dfs(int u)
{
if (u > k)
{
int p = 1;
for (int i = 2; i <= n; i++)
{
if (a[i] > a[1])p++;
}
mi = min(p, mi);
return;
}
a[x[u]] += 3;//a[y[i]]+=0
dfs(u + 1);
a[x[u]] -= 3;
a[y[u]] += 3;
dfs(u + 1);
a[y[u]] -= 3;
a[x[u]]++, a[y[u]]++;
dfs(u + 1);
a[x[u]]--, a[y[u]]--;
}
void solve()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
k = 0;
for (int i = 1; i <= m; i++)
{
int x0, y0;
cin >> x0 >> y0;
if (x0 == 1 || y0 == 1)a[1] += 3;
else x[++k] = x0, y[k] = y0, v[k] = 0;
}
mi = n;
dfs(1);
cout << mi << endl;
}