Khán đài cuối cùng - Đánh bại Zombie Horde


25

Giới thiệu

Bạn đang một mình trên một hòn đảo. Phần còn lại của loài người đã chết ( có lẽ là do lỗi trong mã của user12345 ). Zombie Pirate Horde đã đến hòn đảo của bạn, và chúng là vô tận. Đã đến lúc đá đít hoặc nhai kẹo cao su bong bóng, và tất cả các bạn đều là kẹo cao su bong bóng.

Vấn đề

Kịch bản ngày tận thế của chúng tôi được mô tả bởi 2 số nguyên trên một dòng mn. Trên đảo của bạn là các tiền đồn được đánh số duy nhất từ ​​1 đến m. Sau đây ndòng, mỗi dòng chứa ba số nguyên, x, y, và z, cách nhau bởi một dấu cách. xylà ID duy nhất của hai tiền đồn, và zlà số lượng zombie sẽ gặp phải trên con đường giữa chúng.

Khi bạn đi trên một con đường, bạn mất zđạn và bạn tiêu diệt zzombie. Nếu bạn đi cùng một con đường một lần nữa, bạn sẽ gặp phải số lượng zombie tương tự, thật không may. Tất cả các tiền đồn tạo ra đạn dược +1 mỗi khi bạn đi trên một con đường. Bạn bắt đầu với 100 đạn ở tiền đồn 1. Tất cả các tiền đồn đều bắt đầu bằng 0 đạn. Bạn chết ngay lập tức nếu không có con đường nào tồn tại mà đạn của bạn lớn hơn số lượng zombie trên con đường đó và phần còn lại của đạn được chuyển thành giết. Đó là chỗ đứng cuối cùng của bạn.

Viết chương trình xuất ra số lượng zombie tối đa bạn có thể tiêu diệt cho một kịch bản nhất định. Nếu bạn có thể tiêu diệt vô số zombie, chỉ cần xuất ra x.

Ví dụ đầu vào

5 6
1 2 4
2 3 4
3 1 4
2 4 10
2 5 10
1 1 50

Ví dụ đầu ra

x

Giả định

  • Một đường dẫn sẽ nằm giữa hai tiền đồn hợp lệ. Đó là nói 1 <= x/ y<=m
  • Nếu một con đường giữa xykhông được liệt kê, nó không thể đi được
  • Một đường dẫn là hai chiều
  • 1 m<< = 100
  • 1 n<< = 500
  • Đầu vào phải được cung cấp thông qua stdin, đọc từ tệp hoặc được chấp nhận làm đối số duy nhất cho chương trình và phải chính xác theo định dạng của ví dụ
  • Thời gian chạy chương trình của bạn có thể lớn tùy ý nhưng phải xác định hữu hạn

Mã có ít ký tự nhất sẽ thắng!


Có phải mỗi tiền đồn khác ngoài 1bắt đầu với 0 đạn? Là đồ thị vô hướng?
Peter Taylor

2
Có lẽ cũng hữu ích để loại bỏ trước một loại lỗi nhất định bằng cách có một trường hợp thử nghiệm trong đó có một chu kỳ không chạy hết đạn của bạn nhưng không thể đạt được kịp thời. (Tôi nên nói thêm rằng tôi không tin rằng trường hợp thử nghiệm hiện tại là chính xác: đối với tôi, chu kỳ này 1->1tốn 49 viên đạn và chu kỳ 1->2->3->1tốn 3 viên đạn trong thời gian dài.
Peter Taylor

@PeterTaylor Tôi đã phải rút lại cả hai nhận xét của mình vì có vẻ như tôi đã đưa ra ví dụ hai chiều . Vì vậy, cho phép tôi bắt đầu lại - tất cả các đường dẫn là hai chiều và tất cả các tiền đồn bắt đầu bằng 0. Ví dụ này sẽ hoạt động.
Rainbolt

@Raser: Ví dụ hay! Mất 45 bước để cho tôi thấy rằng nó thực sự bền vững vô cùng. Chúng tôi có thể giả định rằng tất cả các tiền đồn sẽ có thể truy cập được hay bạn muốn chúng tôi xử lý trường hợp có các tiền đồn bị ngắt kết nối khỏi biểu đồ chính?
Claudiu

1
Ahhh ... Vì vậy, đối với mỗi bước từ A đến B, mỗi tiền đồn "tạo ra" một viên đạn và giữ nó ở đó cho đến khi bạn truy cập nó.
Tobia

Câu trả lời:


14

Java ( ít kỳ cục: 8415 5291 3301)

Được. Về cơ bản, tôi xấu hổ không ai gửi giải pháp. Vì vậy, một vài ngày trước tôi đã bắt đầu cố gắng giải quyết vấn đề này, vì nó thật tuyệt. . Theo liên kết đó để xem tiến trình của tôi về nó thông qua GitHub.

Chỉnh sửa

Phiên bản bộ giải mới, "đánh gôn" hơn nhiều, với trình kiểm tra chu kỳ đã sửa được xác định bởi MT0. Nó cũng hỗ trợ các tuyến chuyển tiếp nhanh, có thể điều chỉnh bằng cách thay đổi dung lượng bộ nhớ có sẵn cho VM. Chỉnh sửa BIG mới nhất : nhận ra rằng tôi có một vài lỗi chỉ số nhỏ khác và tối ưu hóa sớm, điều đó dẫn đến việc không xem xét khá nhiều loại chiến thắng. Vì vậy, đó là cố định, cẩn thận. Phiên bản mới nhỏ hơn và nhỏ hơn. Đối với tuyến đường tham chiếu của chúng tôi, java -Xmx2GB ZombieHordeMinthủ thuật này khá độc đáo (được cảnh báo, sẽ mất một lúc).

Thực tế mát mẻ

Trong một vòng xoắn hấp dẫn, có NHIỀU giải pháp ở độ dài 24 và người giải quyết của tôi tìm thấy một giải pháp khác với MT0, nhưng về nguyên tắc giống hệt nhau, ngoại trừ việc nó bắt đầu bằng cách truy cập các tiền đồn khác được kết nối 1. Hấp dẫn! Hoàn toàn chống lại trực giác của con người, nhưng hoàn toàn hợp lệ.

Giải pháp nổi bật

Vậy đây là của tôi. Đó là (một phần) được đánh gôn, vì nó là một người giải quyết theo cấp số nhân, gần như vũ phu. Tôi sử dụng thuật toán IDDFS (tìm kiếm đầu tiên chuyên sâu sâu lặp đi lặp lại), vì vậy đây là một trình giải tổng quát tuyệt vời không bỏ qua, vì vậy nó giải quyết cả hai phần của câu hỏi của OP, cụ thể là:

  • Nếu một tuyến đường chiến thắng được tìm thấy (zombie vô hạn), hãy xuất 'x'.
  • Nếu tất cả các tuyến kết thúc bằng cái chết (zombie hữu hạn), hãy xuất ra số lượng zombie lớn nhất bị giết.

Cung cấp cho nó đủ sức mạnh, bộ nhớ và thời gian, và nó sẽ làm được điều đó, thậm chí cả những bản đồ chết chậm. Tôi đã dành nhiều thời gian hơn để cải thiện bộ giải này, và trong khi có thể làm được nhiều hơn, bây giờ nó đã tốt hơn một chút. Tôi cũng đã tích hợp lời khuyên của MT0 về giải pháp zombie vô hạn tốt nhất và đã loại bỏ một số tối ưu hóa sớm khỏi trình kiểm tra win của tôi để ngăn phiên bản trước tìm thấy nó và thực tế bây giờ tôi tìm thấy một giải pháp rất giống với MT0 được mô tả.

Một vài điểm nổi bật khác:

  • Như đã đề cập, sử dụng IDDFS để tìm ra con đường chiến thắng ngắn nhất có thể.
  • Vì nó là cốt lõi của một DFS, nên nó cũng sẽ khám phá nếu mọi tuyến đường kết thúc bằng cái chết của anh hùng của chúng ta và theo dõi tuyến đường "tốt nhất" trong điều kiện hầu hết zombie bị giết. Chết một anh hùng!
  • Tôi đã sử dụng thuật toán để làm cho nó thú vị hơn khi xem Loại bỏ cho mục đích chơi gôn. Theo một trong các liên kết đến github để xem phiên bản chưa được chỉnh sửa.
  • Cũng có một số ý kiến, vì vậy hãy thoải mái triển khai lại để xây dựng giải pháp của riêng bạn theo cách tiếp cận của tôi, hoặc chỉ cho tôi cách thực hiện!
  • Chuyển tiếp nhanh bộ nhớ thích ứng
    • Lên đến bộ nhớ hệ thống khả dụng, sẽ theo dõi "các tuyến cuối" không dẫn đến tử vong.
    • Sử dụng thói quen nén và giải nén tuyến ưa thích, tiến trình từ lần lặp trước của IDDFS được khôi phục để ngăn chặn việc khám phá lại tất cả các tuyến đã truy cập trước đó.
    • Là một phần thưởng phụ có chủ ý, hoạt động như một con đường chết chóc. Các tuyến đường cụt không được lưu trữ và sẽ không bao giờ được truy cập lại ở độ sâu tương lai của IDDFS.

Lịch sử của người giải

  • Tôi đã thử một loạt các thuật toán nhìn về phía trước một bước, và trong khi đối với các kịch bản rất đơn giản, chúng sẽ hoạt động, cuối cùng chúng bị xẹp.
  • Sau đó, tôi đã thử một thuật toán nhìn về phía trước hai bước, đó là .. không thỏa mãn.
  • Sau đó tôi bắt đầu xây dựng một cái nhìn n bước, khi tôi nhận ra rằng phương pháp này có thể rút gọn thành DFS, nhưng DFS thì ... thanh lịch hơn nhiều.
  • Trong khi xây dựng DFS, đối với tôi, IDDFS sẽ đảm bảo (a) tìm ra tuyến HERO (cái chết) tốt nhất hoặc (b) chu kỳ chiến thắng đầu tiên.
  • Hóa ra việc xây dựng một trình kiểm tra chu kỳ thắng là dễ dàng, nhưng tôi đã phải trải qua một vài lần lặp rất sai trước khi tôi có được một trình kiểm tra thành công có thể chứng minh được.
  • Yếu tố trong đường dẫn chiến thắng của MT0 để loại bỏ ba dòng tối ưu hóa sớm khiến thuật toán của tôi bị mù với nó.
  • Đã thêm một thuật toán lưu trữ tuyến đường thích ứng sẽ sử dụng tất cả bộ nhớ mà bạn cung cấp để ngăn chặn việc làm lại không cần thiết giữa các cuộc gọi IDDFS, đồng thời loại bỏ các tuyến đường cụt đến giới hạn của bộ nhớ.

Mã (được đánh gôn)

Bật mã (lấy phiên bản không được mã hóa ở đây hoặc ở đây ):

import java.util.*;public class ZombieHordeMin{int a=100,b,m,n,i,j,z,y,D=0,R,Z,N;int p[][][];Scanner in;Runtime rt;int[][]r;int pp;int dd;int[][]bdr;int ww;int[][]bwr;int[][]faf;int ff;boolean ffOn;public static void main(String[]a){(new ZombieHordeMin()).pR();}ZombieHordeMin(){in=new Scanner(System.in);rt=Runtime.getRuntime();m=in.nextInt();N=in.nextInt();p=new int[m+1][m+1][N+1];int[]o=new int[m+1];for(b=0;b<N;b++){i=in.nextInt();j=in.nextInt();z=in.nextInt();o[i]++;o[j]++;D=(o[i]>D?o[i]:D);p[i][j][++p[i][j][0]]=z;if(i!=j)p[j][i][++p[j][i][0]]=z;D=(o[j]>D?o[j]:D);}m++;}void pR(){r=new int[5000][m+3];r[0][0]=a;Arrays.fill(r[0],1,m,1);r[0][m]=1;r[0][m+1]=0;r[0][m+2]=0;ww=-1;pp=dd=0;pR(5000);}void pR(int aMD){faf=new int[D][];ff=0;ffOn=true;for(int mD=1;mD<=aMD;mD++){System.out.printf("Checking len %d\n",mD);int k=ffR(0,mD);if(ww>-1){System.out.printf("%d x\n",ww+1);for(int win=0;win<=ww;win++)System.out.printf(" %d:%d,%d-%d",win,bwr[win][0],bwr[win][1],bwr[win][2]);System.out.println();break;}if(k>0){System.out.printf("dead max %d kills, %d steps\n",pp,dd+1);for(int die=0;die<=dd;die++)System.out.printf(" %d:%d,%d-%d",die,bdr[die][0],bdr[die][1],bdr[die][2]);System.out.println();break;}}}int ffR(int dP,int mD){if(ff==0)return pR(dP,mD);int kk=0;int fm=ff;if(ffOn&&D*fm>rt.maxMemory()/(faf[0][0]*8+12))ffOn=false;int[][]fmv=faf;if(ffOn){faf=new int[D*fm][];ff=0;}for(int df=0;df<fm;df++){dS(fmv[df]);kk+=pR(fmv[df][0],mD);}fmv=null;rt.gc();return kk==fm?1:0;}int pR(int dP,int mD){if(dP==mD)return 0;int rT=0;int dC=0;int src=r[dP][m];int sa=r[dP][0];for(int dt=1;dt<m;dt++){for(int rut=1;rut<=p[src][dt][0];rut++){rT++;r[dP+1][0]=sa-p[src][dt][rut]+r[dP][dt];for(int cp=1;cp<m;cp++)r[dP+1][cp]=(dt==cp?1:r[dP][cp]+1);r[dP+1][m]=dt;r[dP+1][m+1]=rut;r[dP+1][m+2]=r[dP][m+2]+p[src][dt][rut];if(sa-p[src][dt][rut]<1){dC++;if(pp<r[dP][m+2]+sa){pp=r[dP][m+2]+sa;dd=dP+1;bdr=new int[dP+2][3];for(int cp=0;cp<=dP+1;cp++){bdr[cp][0]=r[cp][m];bdr[cp][1]=r[cp][m+1];bdr[cp][2]=r[cp][0];}}}else{for(int chk=0;chk<=dP;chk++){if(r[chk][m]==dt){int fR=chk+1;for(int cM=0;cM<m+3;cM++)r[dP+2][cM]=r[dP+1][cM];for(;fR<=dP+1;fR++){r[dP+2][0]=r[dP+2][0]-p[r[dP+2][m]][r[fR][m]][r[fR][m+1]]+r[dP+2][r[fR][m]];for(int cp=1;cp<m;cp++)r[dP+2][cp]=(r[fR][m]==cp?1:r[dP+2][cp]+1);r[dP+2][m+2]=r[dP+2][m+2]+p[r[dP+2][m]][r[fR][m]][r[fR][m+1]];r[dP+2][m]=r[fR][m];r[dP+2][m+1]=r[fR][m+1];}if(fR==dP+2&&r[dP+2][0]>=r[dP+1][0]){ww=dP+1;bwr=new int[dP+2][3];for(int cp=0;cp<dP+2;cp++){bwr[cp][0]=r[cp][m];bwr[cp][1]=r[cp][m+1];bwr[cp][2]=r[cp][0];}return 0;}}}dC+=pR(dP+1,mD);if(ww>-1)return 0;}for(int cp=0;cp<m+3;cp++)r[dP+1][cp]=0;}}if(rT==dC)return 1;else{if(ffOn&&dP==mD-1)faf[ff++]=cP(dP);return 0;}}int[]cP(int dP){int[]cmp=new int[dP*2+3];cmp[0]=dP;cmp[dP*2+1]=r[dP][0];cmp[dP*2+2]=r[dP][m+2];for(int zip=1;zip<=dP;zip++){cmp[zip]=r[zip][m];cmp[dP+zip]=r[zip][m+1];}return cmp;}void dS(int[]cmp){int[]lv=new int[m];int dP=cmp[0];r[dP][0]=cmp[dP*2+1];r[dP][m+2]=cmp[dP*2+2];r[0][0]=100;r[0][m]=1;for(int dp=1;dp<=dP;dp++){r[dp][m]=cmp[dp];r[dp][m+1]=cmp[dP+dp];r[dp-1][cmp[dp]]=dp-lv[cmp[dp]];r[dp][m+2]=r[dp-1][m+2]+p[r[dp-1][m]][cmp[dp]][cmp[dP+dp]];r[dp][0]=r[dp-1][0]+r[dp-1][cmp[dp]]-p[r[dp-1][m]][cmp[dp]][cmp[dP+dp]];lv[cmp[dp]]=dp;}for(int am=1;am<m;am++)r[dP][am]=(am==cmp[dP]?1:dP-lv[am]+1);}}

Lấy mã từ github tại đây, để theo dõi bất kỳ thay đổi nào tôi thực hiện. Dưới đây là một số bản đồ khác tôi đã sử dụng.

Ví dụ đầu ra

Ví dụ đầu ra cho giải pháp tham chiếu:

    $ java -d64 -Xmx3G ZombieHordeMin > reference_route_corrected_min.out
    5 6 1 2 4 2 3 4 3 1 4 2 4 10 2 5 10 1 1 50
    Checking len 1
    Checking len 2
    Checking len 3
    Checking len 4
    Checking len 5
    Checking len 6
    Checking len 7
    Checking len 8
    Checking len 9
    Checking len 10
    Checking len 11
    Checking len 12
    Checking len 13
    Checking len 14
    Checking len 15
    Checking len 16
    Checking len 17
    Checking len 18
    Checking len 19
    Checking len 20
    Checking len 21
    Checking len 22
    Checking len 23
    Checking len 24
    25 x
     0:1,0-100 1:3,1-97 2:1,1-95 3:2,1-94 4:5,1-88 5:2,1-80 6:4,1-76 7:2,1-68 8:1,1-70 9:2,1-68 10:1,1-66 11:2,1-64 12:1,1-62 13:2,1-60 14:1,1-58 15:2,1-56 16:1,1-54 17:2,1-52 18:1,1-50 19:2,1-48 20:1,1-46 21:2,1-44 22:1,1-42 23:2,1-40 24:1,1-38

Đọc đầu ra tuyến đường như thế này step:: source, route-to-get-here- ammo. Vì vậy, trong giải pháp trên, bạn sẽ đọc nó như sau:

  • Ở bước 0, tại tiền đồn 1với đạn 100.
  • Tại bước 1, sử dụng tuyến đường 1để đi đến tiền đồn 3với đạn kết thúc97
  • Tại bước 2, sử dụng tuyến đường 1để đi đến tiền đồn 1với đạn kết thúc95
  • ...

Ghi chú kết thúc

Vì vậy, tôi hy vọng tôi đã làm cho giải pháp của mình khó bị đánh bại hơn, nhưng HÃY THỬ! Sử dụng nó để chống lại tôi, thêm vào một số xử lý song song, lý thuyết đồ thị tốt hơn, v.v ... Một vài điều tôi hình dung có thể cải thiện phương pháp này :

  • tích cực "giảm" các vòng lặp để cắt bỏ việc đọc lại không cần thiết khi thuật toán tiến triển.
    • Một ví dụ: trong bài toán ví dụ, hãy xem xét các vòng lặp 1-2-3 và các hoán vị khác là "một bước", để chúng ta có thể thực hiện theo cách kết thúc chu kỳ nhanh hơn.
    • Ví dụ: nếu bạn ở nút 1, bạn có thể (a) đi đến 2, (b) đi đến 1, (c) đi qua 1-2-3 như một bước và cứ thế. Điều này sẽ cho phép giải quyết để gấp độ sâu thành chiều rộng, tăng số lượng tuyến đường ở độ sâu cụ thể nhưng tăng tốc đáng kể thời gian để giải pháp cho các chu kỳ dài.
  • loại bỏ các tuyến đường chết. Giải pháp hiện tại của tôi không "nhớ" rằng một tuyến đường cụ thể đã hết hạn và phải khám phá lại nó mỗi lần. Sẽ tốt hơn nếu theo dõi khoảnh khắc sớm nhất trong một lộ trình mà cái chết là chắc chắn, và không bao giờ tiến xa hơn nó. đã làm điều này ...
  • nếu cẩn thận, bạn có thể áp dụng loại bỏ tuyến đường chết dưới dạng loại bỏ tuyến phụ. Ví dụ: nếu 1-2-3-4 luôn dẫn đến tử vong và người giải quyết kiểm tra tuyến 1-3-1-2-3-4, thì nó sẽ ngay lập tức dừng xuống đường đó vì nó được bảo đảm kết thúc trong thất vọng. Vẫn có thể tính được số lần giết, với một số phép toán cẩn thận.
  • Bất kỳ giải pháp nào khác trao đổi bộ nhớ theo thời gian hoặc cho phép tránh mạnh mẽ theo các tuyến đường cụt. cũng đã làm điều này

Câu trả lời tốt đẹp! Ai cần đánh golf mã của họ khi họ là người duy nhất có thể giải quyết vấn đề? Bây giờ tôi có động lực để viết giải pháp của riêng mình, vì vậy tôi sẽ làm việc đó.
Rainbolt

Tuyệt vời, đó là những gì tôi hy vọng điều này sẽ làm. Hãy mượn / ăn cắp bất cứ thứ gì từ câu trả lời của tôi mà bạn thấy hữu ích! Mặc dù tất nhiên tôi hy vọng những người khác không chỉ là bản thân tôi và OP sẽ cố gắng giải quyết: P
Lập trình viên

Tôi đã nhận được sidetracked và bắt đầu thu nhỏ mã của bạn. Nếu bạn nghĩ rằng câu trả lời của bạn là kỳ cục trước đây, hãy kiểm tra điều này: tny.cz/17ef0b3a . Vẫn là một công việc đang tiến triển.
Rainbolt

Haha, bạn thực sự đã nhận được sidetracked. Nhìn tốt (kinh khủng thích hợp cho code-golf? Bạn biết ý tôi là gì) cho đến nay!
Lập trình viên

@Rizer Bất kỳ may mắn cho đến nay? Tôi đã có một vài ý tưởng để cải tiến Tôi đã sản xuất, bao gồm kỹ thuật nén đại diện tuyến đường và cách chuyển tiếp nhanh qua các tuyến đã được xử lý (tối đa một điểm).
Lập trình viên

2

Một số ghi chú trừu tượng về một giải pháp

Nếu tôi có thời gian tôi sẽ chuyển đổi nó thành một thuật toán ...

Đối với một biểu đồ đã cho Gthì tồn tại một biểu đồ con được kết nối G'có chứa thị trấn 1. Nếu có một giải pháp vô hạn thì sẽ tồn tại một biểu đồ con được kết nối G''trong G'đó có Vcác thị trấn và Pđường dẫn.

Các đường dẫn Pcủa G''thể được phân chia như vậy mà {p}chứa một con đường trong đó có chi phí sau đó tối thiểu của tất cả các đường dẫn trong PP/{p}là tất cả các con đường khác (tạo thành một cây bao trùm hoặc có thể là một chu kỳ). Nếu chúng ta giả định rằng pkhông phải là một lợi thế cạnh looping (kết nối cả hai đầu đến thị trấn cùng) sau đó nó sẽ kết nối hai thị trấn ( v1v2) và có chi phí cđạn dược sau đó bạn (người sống sót) có thể sau đó đi ngang từ v1đến v2và trở lại với tổng chi phí của 2cđạn và điều này sẽ tăng đạn dược trong tất cả các thị trấn lên 2 (với tổng số gia tăng 2|V|bên trong G''- một số trong đó sẽ được thu thập từ v1v2).

Nếu bạn đi từ v1đến v2và quay lại v1nhiều lần ( m) và sau đó thực hiện một chuyến đi từ v1dọc theo các cạnh P/{p}để đến thăm tất cả các thị trấn khác v1v2trước khi quay lại v1và điều này cần có nnhững con đường để đạt được ( |P/{p}| ≤ n ≤ 2|P/{p}|vì bạn không bao giờ cần phải đi qua một con đường nữa hơn hai lần) với chi phí kvà các thị trấn sẽ thu được 2m|V|đạn dược (một lần nữa một số trong số đó sẽ được thu thập trong quá trình di chuyển).

Với tất cả điều này thì bạn có thể biết liệu một giải pháp vô hạn có khả năng hay không nếu chi phí k + 2mcbằng hoặc thấp hơn tổng phần thưởng 2(m+n)|V|.

Có một sự phức tạp bổ sung cho vấn đề ở chỗ:

  • bạn có thể cần phải đi từ thị trấn bắt đầu 1đến {p}lần lặp đầu tiên và cần phải tính đến chi phí này; và
  • bạn cũng cần đảm bảo rằng mnđủ thấp để bạn không hết đạn trước khi bạn có thể vượt qua lần lặp đầu tiên vì lần lặp đầu tiên sẽ có chi phí cao hơn các lần lặp tiếp theo).

Điều này dẫn đến một giải pháp trung lập chi phí 24 đường dẫn đến ví dụ trong câu hỏi (các số là thị trấn được truy cập):

1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,2,4,2,5,2,3, ... and repeat ...

Một điều nhỏ cần thêm - bạn có thể phải xem xét các cạnh lặp với chi phí là 1, bởi vì các cạnh đó đơn lẻ tạo thành một điều kiện thắng nếu bạn có thể đạt được chúng kịp thời.
Rainbolt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.