日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

7624:山区建小学

發布時間:2024/4/18 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 7624:山区建小学 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接

描述

政府在某山區修建了一條道路,恰好穿越總共m個村莊的每個村莊一次,沒有回路或交叉,任意兩個村莊只能通過這條路來往。已知任意兩個相鄰的村莊之間的距離為di(為正整數),其中,0 < i < m。為了提高山區的文化素質,政府又決定從m個村中選擇n個村建小學(設 0 < n < = m < 500 )。請根據給定的m、n以及所有相鄰村莊的距離,選擇在哪些村莊建小學,才使得所有村到最近小學的距離總和最小,計算最小值。

輸入

第1行為m和n,其間用空格間隔
第2行為(m-1) 個整數,依次表示從一端到另一端的相鄰村莊的距離,整數之間以空格間隔。

例如

10 3
2 4 6 5 2 4 3 1 3
表示在10個村莊建3所學校。第1個村莊與第2個村莊距離為2,第2個村莊與第3個村莊距離為4,第3個村莊與第4個村莊距離為6,…,第9個村莊到第10個村莊的距離為3。

輸出

各村莊到最近學校的距離之和的最小值。

樣例輸入

10 2
3 1 3 1 1 1 1 1 3

樣例輸出

18

AC

  • 在村莊之間建學校,最好建在中點
  • 新建的學校的管轄范圍是它右邊的村莊,它左邊的一個學校到新建學校之間村莊的路程需要枚舉判斷
#include <iostream> #include <algorithm> #include <stdio.h> #include <vector> #include <map> #include <bitset> #include <set> #include <string.h> #include <cmath> #include <queue> #include <algorithm> #define N 505 #define P pair<int,int> #define ll long long #define mk(a, b) make_pair(a, b) #define mem(a, b) memset(a, b, sizeof(a)) using namespace std; int inf = 0x3f3f3f3f; // dp[i][j] 表示建到第i村莊,已經建好j個學校所用的最短路徑 // dis[i] 表示從1到i的距離 // dist[i][j] 表示第i個村莊到第j個村莊的距離 // c[i][j] 表示在第i個村莊和第j個村莊之間建一個學校的路徑長度 int dp[N][N], dis[N], dist[N][N], c[N][N]; int find (int i, int j) { int mid = (i + j) / 2; int sum = 0; for (int k = i; k <= j; ++k) { sum += dist[k][mid]; } return sum; } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int n, m; cin >> n >> m; // 從 1 到 i 的距離 dis[i] for (int i = 2; i <= n; ++i) { cin >> dis[i]; dis[i] += dis[i - 1]; } // i 到 j 的距離 dist[i][j] for (int i = 1; i <= n; ++i) { for (int j = i; j <= n; ++j) { dist[i][j] = dist[j][i] = dis[j] - dis[i]; } } for (int i = 1; i <= n; ++i) { for (int j = i; j <= n; ++j) { c[i][j] = c[j][i] = find(i, j); } } mem(dp, inf); // 修建一所學校 for (int i = 1; i <= n; ++i) { dp[i][1] = c[1][i]; dp[i][i] = 0; } // 枚舉所有學校 for (int i = 2; i <= n; ++i) { // 最多修的學校 for (int j = 2; j <= min(i, m); ++j) { // 枚舉前面一個學校到新建學校的路程 for (int k = j - 1; k < i; ++k) { dp[i][j] = min(dp[i][j], dp[k][j - 1] + c[k + 1][i]); } } } cout << dp[n][m] << endl; return 0; }

總結

以上是生活随笔為你收集整理的7624:山区建小学的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。