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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

poj 1948(搜索+剪枝)

發(fā)布時間:2025/3/16 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj 1948(搜索+剪枝) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

解題思路:這道題看到數(shù)據(jù)量,想到應(yīng)該搜索+剪枝應(yīng)該可以過。。可是別人的A了,我的卻超時了。。。

我用了一個mark[a][b],表示前兩條邊長度分別為a和b時,是否已經(jīng)處理過,如果是的話就直接跳出。。。剩下的就是一個比較簡單的搜索過程了,代碼不難寫,但是確實超時不可避免。。


#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std;const int maxn = 45; int n,len[maxn],s; double half,ans; bool vis[maxn],mark[maxn][maxn];bool cmp(int a,int b) {return a < b; }void dfs(int cur,int a,int b,int dep) {if(mark[a][b] || mark[b][a]) return;if(dep == 3){int c = s - a - b;mark[a][b] = mark[b][a] = true;if(a + b <= c || b + c <= a || a + c <= b) return;double area = half*(half-a)*(half-b)*(half-c);if(area > ans) ans = area;return;}for(int i = cur+1; i <= n; i++){if(vis[i] == true) continue;vis[i] = true;if(dep == 1){dfs(cur+1,a+len[i],b,dep);dfs(0,a+len[i],b,dep+1);}else{dfs(cur+1,a,b+len[i],dep);dfs(0,a,b+len[i],dep+1);}vis[i] = false;} }int main() {while(scanf("%d",&n)!=EOF){s = 0;for(int i = 1; i <= n; i++){scanf("%d",&len[i]);s += len[i];}half = s / 2.0;sort(len+1,len+1+n,cmp);memset(vis,false,sizeof(vis));memset(mark,false,sizeof(mark));ans = -1;dfs(0,0,0,1);if(ans < 0) printf("-1\n");else printf("%d\n",(int)(sqrt(ans)*100));}return 0; }



看了下別人的剪枝,確實比我拓展的節(jié)點要少,同樣mark[i][a][b]表示第i條邊時,最短邊為a,次短邊為b時,是否處理過。。。因為我自己寫的mark[a][b]可能會出現(xiàn)重復(fù)的情況,因為a,b,c的大小關(guān)系并沒有確定好,相同的三角形可能會出現(xiàn)三次,這樣拓展出的新節(jié)點個數(shù)太多,會導(dǎo)致超時的。。。


#include <iostream> #include <cmath>using namespace std;const int MAXN = 41; int fence[MAXN]; bool mark[MAXN][MAXN * MAXN][MAXN * MAXN];int N, s;double hs;void recur(int i, int a, int b, double &maxt) {if(a > s / 3 || mark[i][a][b]){return;}mark[i][a][b] = true;if(i == N){int c = s - a - b;if(a > 0 && b > 0 && c > 0 && a <= b && b <= c && a + b > c){double t = (hs - a) * (hs - b) * (hs - c);if(t > maxt){maxt = t;}}return;}recur(i + 1, a + fence[i], b, maxt);recur(i + 1, a, b + fence[i], maxt);recur(i + 1, a, b, maxt); }int main() {cin>>N;s = 0;for(int i = 0; i < N; ++i){cin>>fence[i];s += fence[i];}hs = s * 1.0 / 2;double maxt = -1;recur(0, 0, 0, maxt);if(maxt < 0){cout<<"-1"<<endl;}else{cout<<(int)(sqrt(maxt * hs) * 100)<<endl;}return 0; }


總結(jié)

以上是生活随笔為你收集整理的poj 1948(搜索+剪枝)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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