UVA307 Sticks小木棍
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                UVA307 Sticks小木棍
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                題意:一開始有n根同樣的小木棍,后來將其切成長(zhǎng)度不超過50的小木棍,問原來小木棍最短長(zhǎng)度是多少,例如砍完后有四根,長(zhǎng)度分別為1,2,3,4,原來長(zhǎng)度可能為5,或10。5是最小可能長(zhǎng)度。
分析:可以用深搜,因?yàn)樗慕M成長(zhǎng)度可能性只是所有木棍長(zhǎng)度總和的因數(shù),所以可以直接dfs。
注意剪枝,四個(gè)剪枝:
1、當(dāng)前枚舉的長(zhǎng)木棍長(zhǎng)度不是小木棍長(zhǎng)的和的因數(shù)時(shí)跳過。
2、與當(dāng)前小木棍長(zhǎng)度相同的小木棍沒有使用,當(dāng)前小木棍也不會(huì)使用。
3、當(dāng)前是拼新的長(zhǎng)木棍的第一個(gè)小木棍,而最后無法拼成的,直接回溯。
4、一根木棍補(bǔ)足長(zhǎng)木棍剩余所需長(zhǎng)度,而最后無法拼成的,直接回溯。
# include<iostream> # include<cstdio> # include<cmath> # include<map> # include<queue> # include<string> # include<string.h> #include<set> #include<list> # include<algorithm> using namespace std; const int maxn = 65536; int a[maxn]; int len; int maxd; int vis[maxn]; bool cmp(int u, int v) { return u > v; } bool dfs(int sum,int cur,int res,int k) {if (res==maxd) {return true;}for (int i =cur ; i < len; i++) {if (vis[i] || (i&&a[i] == a[i - 1] && !vis[i - 1]))continue;//相同長(zhǎng)度的之前沒使用,所以這里一樣不使用if (a[i] + sum == k) {//成功拼成一個(gè)小木塊vis[i] = 1;if (dfs(0, 0, res + 1,k))return true;vis[i] = 0;return false;}if (a[i] + sum < k) {//沒拼好vis[i] = 1;if (dfs(a[i] + sum, i + 1, res,k))return true;vis[i] = 0;if (!sum)return false;//最后仍不能拼成}}return false; }int main() {while (cin >> len && len) {int sum=0;for (int i = 0; i < len; i++) {cin >> a[i];sum += a[i];}int ok = 0;sort(a, a + len,cmp);for (int i = a[0]; i <= sum/2; i++) {//從最大的開始拼if (sum % i == 0) {memset(vis, 0, sizeof(vis));maxd = sum / i;if (dfs(0, 0,0,i)) { cout << i << endl; ok = 1; break; }}}if (!ok)cout << sum << endl;}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的UVA307 Sticks小木棍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 高僧斗法(博弈论)
- 下一篇: UVA - 11882Biggest N
