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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Poj 1011 UVA - 307 Sticks

發(fā)布時間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Poj 1011 UVA - 307 Sticks 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

牛客網(wǎng)
poj 1011

題目:

George took sticks of the same length and cut them randomly until all
parts became at most 50 units long. Now he wants to return sticks to
the original state, but he forgot how many sticks he had originally
and how long they were originally. Please help him and design a
program which computes the smallest possible original length of those
sticks. All lengths expressed in units are integers greater than zero.

Input

The input contains blocks of 2 lines. The first line contains the
number of sticks parts after cutting, there are at most 64 sticks. The
second line contains the lengths of those parts separated by the
space. The last line of the file contains zero.

Output

The output should contains the smallest possible length of original
sticks, one per line.

Sample Input

9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0

Sample Output

6 5

題意:

一組等長木棍,砍成n份,現(xiàn)將n份重新組合,問原木棍的長度

題解:

dfs+剪枝
思路就是枚舉每一種長度的可能,然后去驗證是否成立
如果直接這樣做肯定超時,我們需要優(yōu)化,也就是剪枝
1.將原木棍的長度從小到大排列,并按照這個順序進行搜索,原木棍的長度肯定在1~所有木棍之和范圍內(nèi),也大于等于現(xiàn)所有木棍
2.如果我們探究第x個木塊是否能匹配,如果與第i個木棍不能拼成假設長度,則和第i個木棍一樣長的都不可以,這樣可以跳過一批
3。如果對于一個木棍,找不到任何一個或多個木棍拼成預設原木棍長度,那說明該預設原木棍長度不存在,枚舉下一個
對應代碼部分就是

if(ret==a[i] || len==ret)break;

我是這么理解的:
ret = = a[i]表示可以與a[i],但是之后的木棍無法拼上,依舊不符合題意
len = = ret說明之后的任何一個木棍都拼不上

代碼:

#include<iostream> #include<algorithm> #include<cstring> using namespace std; int sum,a[100]; bool vis[100]; bool cmp(int a,int b){return a>b; } int dfs(int len,int n,int stick,int ret) {if(stick==n && ret==0)//ret是代表的是以及一個棒已經(jīng)拼的長度的return len;//如果所有的棒都已經(jīng)用完的話 if(ret==0)//這代表一個已經(jīng)拼完啦!ret=len;int i;for(i=0; i<n; i++){if(vis[i]==true)continue;if(a[i]>ret)continue;//代表的是已經(jīng)不滿足題意了,直接要跳出大循環(huán)的vis[i]=true;if(dfs(len,n,stick+1,ret-a[i])) //如果當前木棍與其他木棍拼成功 return len;vis[i]=false; if(ret==a[i] || len==ret)//最重要的剪枝,如果找不到任意一個枝和當前的枝進行匹配,則說明不可能對了,就直接跳出大循環(huán)的!break;while(a[i]==a[i+1])//剪枝二,dfs的木塊與第i根沒有拼成的話,第i+1根和第i根長度相同的話也就拼不成了,剪去的{printf("a[i]=%d,ret=%d,len=%d\n",a[i],ret,len);i++;}}return 0; } int main() {int i,j,n,k;while(1){cin>>n;if(n==0)break;sum=0;for(i=0; i<n; i++){cin>>a[i];sum+=a[i];}sort(a,a+n,cmp);//剪枝一,按照棍子從大到小排列的,然后直接舍棄總棍子太小的for(i=a[n]; i<=sum; i++){if(sum%i!=0)continue;//本來就不可以的啊memset(vis,0,sizeof(vis));k=dfs(i,n,0,i);//預設原木棍長度(固定的) 木棍總塊數(shù) 所用木棍的數(shù)量 還需要拼的長度(不斷變化) if(k!=0)break;}cout<<k<<endl;}return 0; }

另外 sort與qsort:

qosrt和sort我一直認為是qsort快,但也有說sort快的,我也是一臉懵逼

int num[maxn];int cmp ( const void *a , const void *b ) { return *(int *)a - *(int *)b;}qsort(num,maxn,sizeof(int),cmp);

總結(jié)

以上是生活随笔為你收集整理的Poj 1011 UVA - 307 Sticks的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。