結果
問題 | No.134 走れ!サブロー君 |
ユーザー |
|
提出日時 | 2019-06-29 12:29:58 |
言語 | Go (1.23.4) |
結果 |
AC
|
実行時間 | 22 ms / 5,000 ms |
コード長 | 9,013 bytes |
コンパイル時間 | 15,949 ms |
コンパイル使用メモリ | 236,896 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-07-02 05:31:10 |
合計ジャッジ時間 | 16,741 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 15 |
ソースコード
package mainimport ("bufio""errors""fmt""io""math""os""strconv")/********** I/O usage **********///str := ReadString()//i := ReadInt()//X := ReadIntSlice(n)//S := ReadRuneSlice()//a := ReadFloat64()//A := ReadFloat64Slice(n)//str := ZeroPaddingRuneSlice(num, 32)//str := PrintIntsLine(X...)/*******************************************************************/const MOD = 1000000000 + 7const ALPHABET_NUM = 26const INF_INT64 = math.MaxInt64const INF_BIT60 = 1 << 60var xo, yo intvar n intvar X, Y []intvar W []float64var dp [1 << 13][13]float64func main() {xo, yo = ReadInt(), ReadInt()n = ReadInt()X, Y = make([]int, n), make([]int, n)W = make([]float64, n)for i := 0; i < n; i++ {x, y, w := ReadInt(), ReadInt(), ReadFloat64()X[i], Y[i], W[i] = x, y, w}for S := 0; S < (1 << uint(n)); S++ {for j := 0; j < n; j++ {dp[S][j] = float64(INF_BIT60)}}// dp[0][0] = 0.0for S := 0; S < (1 << uint(n)); S++ {for j := 0; j < n; j++ {// 酒屋から最初の配達場所if S == 0 {dist := AbsInt(X[j]-xo) + AbsInt(Y[j]-yo)weight := getWeight(S)time := float64(dist) * ((weight + 100.0) / 120.0)dp[S|1<<uint(j)][j] = math.Min(dp[S|1<<uint(j)][j], time+W[j])continue}//配達場所k -> 配達場所jfor k := 0; k < n; k++ {if NthBit(S, j) == 0 && NthBit(S, k) == 1 {dist := AbsInt(X[k]-X[j]) + AbsInt(Y[k]-Y[j])weight := getWeight(S)time := float64(dist) * ((weight + 100.0) / 120.0)dp[S|1<<uint(j)][j] = math.Min(dp[S|1<<uint(j)][j], dp[S][k]+time+W[j])}}}}res := float64(INF_BIT60)for k := 0; k < n; k++ {res = math.Min(res, dp[1<<uint(n)-1][k]+(100.0/120.0)*float64(AbsInt(X[k]-xo)+AbsInt(Y[k]-yo)))}fmt.Println(res)// for i := 0; i < (1 << uint(n)); i++ {// fmt.Println(dp[i][:n])// }// fmt.Println(getWeight(1<<uint(n) - 1))// fmt.Println(getWeight(0))}func getWeight(SS int) float64 {res := 0.0for j := 0; j < n; j++ {if NthBit(SS, j) == 0 {res += W[j]}}return res}// MODはとったか?// 遷移だけじゃなくて最後の最後でちゃんと取れよ?/*******************************************************************//*********** I/O ***********/var (// ReadString returns a WORD string.ReadString func() stringstdout *bufio.Writer)func init() {ReadString = newReadString(os.Stdin)stdout = bufio.NewWriter(os.Stdout)}func newReadString(ior io.Reader) func() string {r := bufio.NewScanner(ior)r.Buffer(make([]byte, 1024), int(1e+11))// Split sets the split function for the Scanner. The default split function is ScanLines.// Split panics if it is called after scanning has started.r.Split(bufio.ScanWords)return func() string {if !r.Scan() {panic("Scan failed")}return r.Text()}}// ReadInt returns an integer.func ReadInt() int {return int(readInt64())}func readInt64() int64 {i, err := strconv.ParseInt(ReadString(), 0, 64)if err != nil {panic(err.Error())}return i}// ReadIntSlice returns an integer slice that has n integers.func ReadIntSlice(n int) []int {b := make([]int, n)for i := 0; i < n; i++ {b[i] = ReadInt()}return b}// ReadFloat64 returns an float64.func ReadFloat64() float64 {return float64(readFloat64())}func readFloat64() float64 {f, err := strconv.ParseFloat(ReadString(), 64)if err != nil {panic(err.Error())}return f}// ReadFloatSlice returns an float64 slice that has n float64.func ReadFloat64Slice(n int) []float64 {b := make([]float64, n)for i := 0; i < n; i++ {b[i] = ReadFloat64()}return b}// ReadRuneSlice returns a rune slice.func ReadRuneSlice() []rune {return []rune(ReadString())}/*********** Debugging ***********/// ZeroPaddingRuneSlice returns binary expressions of integer n with zero padding.// For debugging use.func ZeroPaddingRuneSlice(n, digitsNum int) []rune {sn := fmt.Sprintf("%b", n)residualLength := digitsNum - len(sn)if residualLength <= 0 {return []rune(sn)}zeros := make([]rune, residualLength)for i := 0; i < len(zeros); i++ {zeros[i] = '0'}res := []rune{}res = append(res, zeros...)res = append(res, []rune(sn)...)return res}/*********** DP sub-functions ***********/// ChMin accepts a pointer of integer and a target value.// If target value is SMALLER than the first argument,// then the first argument will be updated by the second argument.func ChMin(updatedValue *int, target int) bool {if *updatedValue > target {*updatedValue = targetreturn true}return false}// ChMax accepts a pointer of integer and a target value.// If target value is LARGER than the first argument,// then the first argument will be updated by the second argument.func ChMax(updatedValue *int, target int) bool {if *updatedValue < target {*updatedValue = targetreturn true}return false}// NthBit returns nth bit value of an argument.// n starts from 0.func NthBit(num, nth int) int {return num >> uint(nth) & 1}// OnBit returns the integer that has nth ON bit.// If an argument has nth ON bit, OnBit returns the argument.func OnBit(num, nth int) int {return num | (1 << uint(nth))}// OffBit returns the integer that has nth OFF bit.// If an argument has nth OFF bit, OffBit returns the argument.func OffBit(num, nth int) int {return num & ^(1 << uint(nth))}// PopCount returns the number of ON bit of an argument.func PopCount(num int) int {res := 0for i := 0; i < 70; i++ {if ((num >> uint(i)) & 1) == 1 {res++}}return res}/*********** Arithmetic ***********/// Max returns the max integer among input set.// This function needs at least 1 argument (no argument causes panic).func Max(integers ...int) int {m := integers[0]for i, integer := range integers {if i == 0 {continue}if m < integer {m = integer}}return m}// Min returns the min integer among input set.// This function needs at least 1 argument (no argument causes panic).func Min(integers ...int) int {m := integers[0]for i, integer := range integers {if i == 0 {continue}if m > integer {m = integer}}return m}// DigitSum returns digit sum of a decimal number.// DigitSum only accept a positive integer.func DigitSum(n int) int {if n < 0 {return -1}res := 0for n > 0 {res += n % 10n /= 10}return res}// Sum returns multiple integers sum.func Sum(integers ...int) int {s := 0for _, i := range integers {s += i}return s}// CeilInt returns the minimum integer larger than or equal to float(a/b).func CeilInt(a, b int) int {res := a / bif a%b > 0 {res++}return res}// FloorInt returns the maximum integer smaller than or equal to float(a/b)func FloorInt(a, b int) int {res := a / breturn res}// PowInt is integer version of math.Pow// PowInt calculate a power by Binary Power (二分累乗法(O(log e))).func PowInt(a, e int) int {if a < 0 || e < 0 {panic(errors.New("[argument error]: PowInt does not accept negative integers"))}if e == 0 {return 1}if e%2 == 0 {halfE := e / 2half := PowInt(a, halfE)return half * half}return a * PowInt(a, e-1)}// AbsInt is integer version of math.Absfunc AbsInt(a int) int {if a < 0 {return -a}return a}// Gcd returns the Greatest Common Divisor of two natural numbers.// Gcd only accepts two natural numbers (a, b >= 1).// 0 or negative number causes panic.// Gcd uses the Euclidean Algorithm.func Gcd(a, b int) int {if a <= 0 || b <= 0 {panic(errors.New("[argument error]: Gcd only accepts two NATURAL numbers"))}if a < b {a, b = b, a}// Euclidean Algorithmfor b > 0 {div := a % ba, b = b, div}return a}// Lcm returns the Least Common Multiple of two natural numbers.// Lcd only accepts two natural numbers (a, b >= 1).// 0 or negative number causes panic.// Lcd uses the Euclidean Algorithm indirectly.func Lcm(a, b int) int {if a <= 0 || b <= 0 {panic(errors.New("[argument error]: Gcd only accepts two NATURAL numbers"))}// a = a'*gcd, b = b'*gcd, a*b = a'*b'*gcd^2// a' and b' are relatively prime numbers// gcd consists of prime numbers, that are included in a and bgcd := Gcd(a, b)// not (a * b / gcd), because of reducing a probability of overflowreturn (a / gcd) * b}// Strtoi is a wrapper of `strconv.Atoi()`.// If `strconv.Atoi()` returns an error, Strtoi calls panic.func Strtoi(s string) int {if i, err := strconv.Atoi(s); err != nil {panic(errors.New("[argument error]: Strtoi only accepts integer string"))} else {return i}}// PrintIntsLine returns integers string delimited by a space.func PrintIntsLine(A ...int) string {res := []rune{}for i := 0; i < len(A); i++ {str := strconv.Itoa(A[i])res = append(res, []rune(str)...)if i != len(A)-1 {res = append(res, ' ')}}return string(res)}