51nod 1625 夹克爷发红包(dfs,暴力)

    技术2022-07-10  149

    1625 夹克爷发红包

    题目

    在公司年会上,做为互联网巨头51nod掌门人的夹克老爷当然不会放过任何发红包的机会。

    现场有n排m列观众,夹克老爷会为每一名观众送出普通现金红包,每个红包内金额随机。

    接下来,夹克老爷又送出最多k组高级红包,每组高级红包会同时给一排或一列的人派发 ,每个高级红包的金额皆为x。

    派发高级红包时,普通红包将会强制收回。同时,每个人只能得到一个高级红包。(好小气!)

    现在求一种派发高级红包的策略,使得现场观众获得的红包总金额最大。

    输入

    第一行为n, m, x, k四个整数。

    1 <= n <= 10, 1 <= m <= 200 1 <= x <= 10^9,0 <= k <= n + m

    接下来为一个n * m的矩阵,代表每个观众获得的普通红包的金额。普通红包的金额取值范围为1 <= y <= 10^9

    输出

    输出一个整数,代表现场观众能获得的最大红包总金额

    输入样例

    3 4 1 5 10 5 7 2 10 5 10 8 3 9 5 4

    输出样例

    78

    代码实现
    #include <iostream> #include <string> #include <algorithm> #include <cstring> #include <cmath> #define ll long long using namespace std; ll a[15][250], b[15][250], vis[250], all[250]; ll ans = 0; ll n, m, x, k; void solve() { // 行使用高级红包次数 ll used = 0; for (int i = 0; i < n; i++) { if (vis[i]) { used++; } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (vis[i]) { b[i][j] = x; } else { b[i][j] = a[i][j]; } } } ll sum = 0; memset(all, 0, sizeof(all)); for (int j = 0; j < m; j++) { for (int i = 0; i < n; i++) { all[j] += b[i][j]; sum += b[i][j]; } } // 剩余可用高级红包次数 int use = k - used; sort(all, all + m); for (int i = 0; i < m; i++) { if (all[i] < n * x && use > 0) { sum -= all[i]; sum += n * x; use--; } } ans = max(ans, sum); } void dfs(int h, int sum) { // h 行发高级红包 if (sum > k) { return; } if (h == n) { solve(); } else { // h 行要高级红包 vis[h] = 1; dfs(h + 1, sum + 1); vis[h] = 0; dfs(h + 1, sum); } } int main() { memset(vis, 0, sizeof(vis)); cin >> n >> m >> x >> k; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { scanf("%lld", &a[i][j]); } } dfs(0, 0); printf("%lld\n", ans); return 0; }
    Processed: 0.012, SQL: 9