題目意思:
你是乙個修水管的工人。在乙個1000*1000的座標系中需要用水管聯通兩個城市。顯然,為了讓你的工作變得簡單,你的老闆決定水管只能橫著或者豎著放。有一些不同型號的水管,會告訴你每一種水管的長度和數量。現在你要做的是求出最少能夠接通兩個城市的水管數量。
輸入:
只有一組資料啦啦~~
首先兩個數,代表城市1的橫縱座標;
然後再來兩個數,代表城市2的橫縱座標;
然後是乙個數n,代表有n種型號的水管;
再之後是n個數,代表每種型號水管的長度;
又是n個數,代表每種型號水管的數量。
輸出:
最少需要的水管數量;
要是無解,則輸出-1。
ps:這個水管是比較有特色的,因為他們可以交叉、重疊。比如,下面兩組水管也是合法的:
第一組:
水管1: 1,1 1,2 1,3
水管2: 1,2 2,2 2,3
第二組:
水管1: 1,1 1,2 1,3
水管2: 1,1 1,2
講不清楚這個特色,大家自己看看這兩組水管吧:)
現在開始講怎麼做~~
首先,我們答案無非分為兩種:有答案還是沒答案;
顯然,我們只需要考慮有答案的:
如果起點和終點是同乙個點,那麼就不需要你修了(答案直接是0);
否則 假設所有水管的數量和為sum;
那麼,我們的答案就是在[1,sum]這個區間裡了~
for(ans=1;ans
<=sum;ans++)
if(pd(ans))break;
顯然,我們要的只是最少的水管數量。
於是,接下來要用到一種神奇的ida*演算法(具體看**吧);
#include
#include
#include
#include
#include
const
int maxn=1010;
using
namespace
std;
int sx,sy,ex,ey,n,hx[1010],hy[1010],sum,ans;
struct sticka[20];
void bfs(int *h,int x)if(x+a[i].l<=1000&&h[x+a[i].l]==-1)}}
}bool pd(stick *a,int x,int d,int k)
for(int i=1;i<=n;i++)
tmp[i]=a[i];//由於涉及到修改木棍數量,所以要乙個臨時陣列
for(int i=1;i<=n;i++)
return
false;
}int main()
//每種水管的數量,sum記得累加
if(sx==ex&&sy==ey);
//要是不用走,那直接 return 0; 就好了
memset(hx,-1,sizeof(hx));
memset(hy,-1,sizeof(hy));
bfs(hx,ex);
bfs(hy,ey);
//需要這個步驟先算一遍
for(ans=1;ans<=sum;ans++)
if(pd(a,sx,0,0))
break;
if(ans>sum)
else
printf("%d\n",ans);
return
0;}
poj 1033 Defragment 解題報告
距離從1000處子題,已經過了好些日子了,終於突破20題了,但是還沒有進入前1w 中國的人真多啊 一直在做動態規劃的題,實在是被動態規劃的強大折服。最近開始找些搜尋的題來做,剪那個sticks,一直剪不過tle,於是決定換道題,看網上的推薦說這是一道搜尋題,於是開始切!題意 磁碟整理,按照從第乙個檔...
poj1007 DNA Sorting解題報告
題目要求的是一條dna序列的逆序數,求逆序數可以考慮使用歸併演算法來進行求解。我們來設想這樣乙個場景 相鄰的a b兩塊進行公升序排序,各自都已經是排好序的了,且b排在a右邊。那麼當把b中的某數t放到已排序的數列中,那麼a序列中剩下的數就是比數t要大的,但我們要注意到 在原序列中,由於b序列在a序列右...
poj 1007DNA Sorting解題報告
默默的說真的是水題 題目大意 序列 未排序程度 的乙個計算方式是元素亂序的元素對個數。例如 在單詞序列 daabec 中,因為d大於右邊四個單詞,e大於c,所以計算結果為5。這種計算方法稱為序列的逆序數。序列 aacedgg 逆序數為1 e與d 近似排序,而序列 zwqm 逆序數為6 它是已排序序列...