2 条题解

  • 1
    @ 2023-12-10 20:51:56

    一道dp配搜索

    # include <bits/stdc++.h>
    using namespace std;
    long long n, m, h;
    long long dp[510][510], a[1010], b[1010];
    void dfs(int i, int j) {
    	for (int k = 1; k <= i; k++) {
    		if (k != 0 && i != 0 && h >= max(b[i] - b[k - 1], dp[k - 1][j - 1])) {
    			dfs(k - 1, j - 1);
    			cout << k << " " << i << "\n";
    			break;
    		}
    	}
    }
    int main() {
    	cin >> m >> n;
    	memset(dp, 0x3f, sizeof(dp));
    	for (int i = 1; i <= m; i++) {
    		cin >> a[i];
    		b[i] = b[i - 1] + a[i];
    	}
    	dp[0][0] = 0;
    	for (int i = 1; i <= m; i++) {
    		for (int j = 1; j <= n; j++) {
    			if (i < j) {
    				dp[i][j] = dp[i][i];
    				continue;
    			}
    			for (int k = j; k <= i; k++) {
    				dp[i][j] = min(dp[i][j], max(b[i] - b[k - 1], dp[k - 1][j - 1]));
    			}
    		}
    	}
    	h = dp[m][n];
    	dfs(m, n);
    	return 0;
    }
    
    • 0
      @ 2023-7-24 22:50:23

      使用二分进行处理,

      二分每个人要抄的的页数,

      看人数够不够就可以了。

      如果人数不够,每个人就多抄几页;

      否则每个人就少抄几页。

      到最后每个人抄的页数最少,那么时间也最少。

      #include <bits/stdc++.h>
      
      using namespace std;
      
      const int N = 510, INF = 0x3f3f3f3f;
      
      int m, k;
      int a[N];
      int sum;
      int cx[N];
      int cnt;
      int st[N];
      
      bool check(int x) {
          cnt = 0; cx[0] = INF; st[0] = m + 1;
          for (int i = m; i >= 1; i--) {
              if (cx[cnt] + a[i] <= x) {
                  cx[cnt] += a[i];
                  st[cnt] = i;
              }
              else {
                  cnt++;
                  cx[cnt] = a[i];
                  st[cnt] = i;
              }
          }
          return cnt <= k;
      }
      
      int main() {
          ios::sync_with_stdio(false);
          cin.tie(nullptr);
      
          cin >> m >> k;
          for (int i = 1; i <= m; i++) cin >> a[i], sum += a[i];
      
          int l = 0, r = sum;
          while (l < r) {
              int mid = (l + r) >> 1;
              if (check(mid)) r = mid;
              else l = mid + 1;
          }
          check(l);
          for (int i = cnt; i >= 1; i--) cout << st[i] << ' ' << st[i - 1] - 1 << '\n';
          return 0;
      }
      
      • 1

      信息

      ID
      282
      时间
      1000ms
      内存
      125MiB
      难度
      4
      标签
      递交数
      5
      已通过
      3
      上传者