結果
| 問題 |
No.4 おもりと天秤
|
| コンテスト | |
| ユーザー |
seiichi
|
| 提出日時 | 2021-01-21 14:28:54 |
| 言語 | Go (1.23.4) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 1,312 bytes |
| コンパイル時間 | 16,690 ms |
| コンパイル使用メモリ | 229,112 KB |
| 実行使用メモリ | 6,820 KB |
| 最終ジャッジ日時 | 2024-12-24 14:17:08 |
| 合計ジャッジ時間 | 13,387 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 13 WA * 10 |
ソースコード
package main
import "fmt"
func scan() (N int, W []int) {
fmt.Scan(&N)
for i := 0; i < N; i++ {
var w int
fmt.Scan(&w)
W = append(W, w)
}
return
}
func main() {
N, W := scan()
// N, W := 3, []int{1, 2, 3}
// N, W := 15, []int{62, 8, 90, 2, 24, 62, 38, 64, 76, 60, 30, 76, 80, 74, 72}
var sum int
for _, w := range W {
sum += w
}
var expectedWeight int
res := "impossible"
if sum%2 != 0 {
// 割り切れない場合は水平にならない
fmt.Print(res)
return
} else {
expectedWeight = sum / 2
}
// すべての組み合わせを計算するとO(2^N)となってしまう
// 動的計画法を使って、Nが2から100のすべてのパターンにおいて、可能性のある数値の組み合わせを順番にマッピングしていく
// どこかでexpectedWeightと一致する値が見つかればそこで終了するようにする
// こうすることで、O(N*W*W)となる
// N=100, W=100で考えてみると
// 1.2676506e+30 (2^N) vs 100,000(N*W*W) で歴然
var dp [100][100*100 + 1]bool
dp[0][W[0]] = true
for i := 1; i < N; i++ {
dp[i][W[i]] = true
for j := 0; j < len(dp[i-1]); j++ {
if dp[i-1][j] {
dp[i][j+W[i]] = true
}
}
if dp[N-1][expectedWeight] {
res = "possible"
goto Exit
}
}
Exit:
fmt.Print(res)
}
seiichi