九度OJ 1251:序列分割 (DFS)
時間限制:1 秒
記憶體限制:32 兆
特殊判題:否
提交:166
解決:34
- 題目描述:
-
一個整數陣列,長度為n,將其分為m份,使各份的和相等,求m的最大值
比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1;
{3,6}{2,4,3} m=2
{3,3}{2,4}{6} m=3 所以m的最大值為3。
- 輸入:
-
存在多組資料,每組資料一定行為一個正整數n(n<=64),第二行為n個數字。當n為0時,測試結束。
- 輸出:
-
輸出最大值m。
- 樣例輸入:
-
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
- 樣例輸出:
-
4 2
思路:
剪枝1:由大到小順序排列,每次選擇重上次選擇的後一個開始。
剪枝2:如果一個數字把一組填滿了,不需要考慮用更小的木棍填補這一組了,進行對下一組的搜尋。
剪枝3:設對一組的搜尋開始時,當前尚未用的最大的數字是a,如果把a選入不行,那麼目前的狀態應捨棄,因為這個數字a是必然要處理的,而放到後面處理,只會可用數字更少,而亦必然不可以。
剪枝4:由於數字已排序,前面一個數字嘗試後不行,則跳過下面同樣的數字。
這個題目很經典。黑書上有講過,但其只錯誤的強調了剪枝2的效用,而事實上剪枝3是最強且必須的,需要注意。
程式碼:
#include <stdio.h> #include <stdlib.h> #include <string.h> int cmp(const void *a, const void *b) { return (*(int *)a < *(int *)b) * 2 - 1; } int n, A[100], sum; int mark[100], ans, full; int dfs(int cnt, int max, int re, int s) { if (cnt == 0) return 1; if (re == 0) { return dfs(cnt-1, max, max, 0); } int i; for (i=s; i<n; i++) { if (mark[i] || re-A[i] < 0) continue; mark[i] = 1; if (dfs(cnt, max, re-A[i], i+1)) return 1; mark[i] = 0; if (re-A[i] == 0) break; if (max == re) break; //the largest number have try, and failed, cut // not sucess, skip the same number while (A[i+1] == A[i] && i+1<n) i++; } return 0; } int Try(int len) { if (sum % len != 0) return 0; memset(mark, 0, sizeof mark); return dfs(sum/len, len, len, 0); } void Solve() { qsort(A, n, sizeof(int), cmp); int m = A[0]; while (!Try(m)) m++; printf("%d\n", sum/m); } int main() { int i, j; while (scanf("%d", &n), n) { for (sum=i=0; i<n; i++) scanf("%d", &A[i]), sum+=A[i]; Solve(); } return 0; }
相關推薦
九度OJ 1251:序列分割 (DFS)
時間限制:1 秒 記憶體限制:32 兆 特殊判題:否 提交:166 解決:34 題目描述: 一個整數陣列,長度為n,將其分為m份,使各份的和相等,求m的最大值 比如{3,2,
九度OJ 1052:找x (基礎題)
時間限制:1 秒 記憶體限制:32 兆 特殊判題:否 提交:7335 解決:3801 題目描述: 輸入一個數n,然後輸入n個數值各不相同,再輸入一個值x,輸出這個值在這個陣列中的
九度OJ 1133:學分績點 (加權平均數)
時間限制:1 秒 記憶體限制:32 兆 特殊判題:否 提交:1333 解決:702 題目描述: 北京大學對本科生的成績施行平均學分績點制(GPA)。既將學生的實際考分根據不同的學
九度OJ 1014:排名 (排序)
時間限制:1 秒 記憶體限制:32 兆 特殊判題:否 提交:8267 解決:2469 題目描述: 今天的上機考試雖然有實時的Ranklist,但上面的排名只是根據完成的題數
九度OJ 1008:最短路徑問題 (最短路)
時間限制:1 秒 記憶體限制:32 兆 特殊判題:否 提交:8064 解決:2685 題目描述: 給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。 輸入
九度OJ 1482:瑪雅人的密碼
清華 sizeof swap name substr wap 如果 found www 題目描述: 瑪雅人有一種密碼,如果字符串中出現連續的2012四個數字就能解開密碼。給一個長度為N的字符串,(2=<N<=13)該字符串中只含有0,1,2三種數字,問這個字符串
九度OJ-1457:非常可樂
本題也是轉化為狀態建立解答樹並剪枝,然後進行廣度優先搜尋。 Debug記錄: ①找了很久,最後發現是mark陣列的初始化除了問題,原始碼如下: for (int i=1;i<=S;i++){ for (int j=1;j<=N;j++){
九度OJ-1208:10進位制 VS 2進位制
本題使用了寫好的高精度整數的模板,將ten2N()函式的輸出方式稍微改了改。 debug過程: ①過載的*運算通過這道題發現了bug:當輸入的int x為0時,由於使用的是BigInt與int逐位乘的演算法,故若BigInt的intSize不為1的話,會return一個
九度OJ 1208: 10進位制 VS 2進位制
#include <stdio.h> #include <stdlib.h> #include <string.h> void swap(int *p, int *q) { int temp; temp = *p; *p = *q; *
九度OJ 1081: 遞推數列
#include <stdio.h> #include <stdlib.h> #define MOD 10000 //結果取MOD,避免高精度運算 /*將矩陣p與矩陣q相乘,結果存入p矩陣*/ void Matrix_mul(int p[2][2], int q[2][
九度OJ-1450:產生冠軍
這道題厲害了。= =想不明白 演算法分析: 由於這裡的優先關係具有傳遞性,故可利用有向圖表示優先關係:“A優勝於C”==可抽象為==》“A到C之間存在有向路徑”。有了這層抽象就能進行以下分析: ①“不能出現迴圈優先關係”《==》不能出現環路:進行拓撲排序來檢測有無環
九度OJ 1455: 珍惜現在,感恩生活
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Food //糧食結構體 { int price; int wei
題目1251:序列分割(DFS+剪枝)
題目描述: 一個整數陣列,長度為n,將其分為m份,使各份的和相等,求m的最大值 比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1; {3,6}{2,4,3} m=2 {3,3}{2,4}{6} m=3 所以m的最大值為3。 輸入: 存在多
九度OJ-1144:Freckles
依然是最小生成樹問題,使用並查集+kruskal實現。不贅述。 題目描述: In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's b
九度OJ 1003:A+B
時間限制:1 秒 記憶體限制:32 兆 特殊判題:否 提交:15078 解決:6299 題目描述: 給定兩個整數A和B,其表示形式是:從個位開始,每三位數用逗號","隔開。 現在請
九度OJ 1088: 剩下的樹
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int l, m; while(scanf("%d%d", &l, &m) != EOF)
九度Oj 1123: 採藥
題目描述: 辰辰是個很有潛能、天資聰穎的孩子,他的夢想是稱為世界上最偉大的醫師。 為此,他想拜附近最有威望的醫師為師。醫師為了判斷他的資質,給他出了一個難題。 醫師把他帶到個到處都是草藥的山洞裡對他說: “孩子,這個山洞裡有一些不同的草藥,採每一株都需要一些時間,每一株也
資料結構實驗之棧與佇列十:走迷宮(DFS)
Problem Description 一個由n * m 個格子組成的迷宮,起點是(1, 1), 終點是(n, m),每次可以向上下左右四個方向任意走一步,並且有些格子是不能走動,求從起點到終點經過每個格子至多一次的走法數。 Input 第一行一個整數T
洛谷1101:單詞方陣(DFS)
題目描述 給一n×nn \times nn×n的字母方陣,內可能蘊含多個“yizhong”單詞。單詞在方陣中是沿著同一方向連續擺放的。擺放可沿著888個方向的任一方向,同一單詞擺放時不再改變方向,單詞與單詞之間可以交叉,因此有可能共用字母。輸出時,將不是單詞的字
九度 OJ 題目1008:最短路徑問題 (Dijstra 演算法)
題目描述: 給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。 輸入: 輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為