388 words
2 minutes
[BOJ] 막대 정사각형
TimeLimit | MemoryLimit | Condition | TAG |
---|---|---|---|
1s | 128MB | (1 ≤ N ≤ 20, 1 ≤ stick_length ≤ 10,000) | Dynamic Programming |
약간 날먹 느낌의 dp였구용. 친구가 추천해줘서 풀었는데 그래도 조금 괜찮은 플레 dp 문제였습니다.
어차피 만들어야할 정사각형은 정해져잇으니 그거 targeting해서 문제풀면 쉬웠던 문제였어용.
정답 코드
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <sstream>
#include <iomanip>
#include <string>
#include <numeric>
#include <unordered_set>
#include <unordered_map>
#include <climits>
using namespace std;
using ll = unsigned long long;
//ll MOD = 1'000'000'007;
ll MOD = 1.8446744074E19;
int T, N;
int sticks[21];
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> T;
while(T --> 0){
cin >> N;
int sum = 0;
for(int i = 0; i < N; i++) {
cin >> sticks[i];
sum += sticks[i];
}
int dp[(1 << N) + 1];
int length = (1 << N) + 1;
for(int i = 0; i < length; i++) dp[i] = -1;
// visited 를 dp[i]로 처리한다. 즉 뭐를 처리했는가에 대한 dp식으로 간주하고, dp[i]는
// 그리고 결국 만들 수 있는 최대 정사각형은.. 20 * 20이 최대일 것이다...
// 그래서 width와 height가 n인 정사각형인 것을 알고서 말하면 될 듯?
if(sum % 4 != 0) {
cout << "no\n";
continue;
}
int target = sum / 4;
dp[0] = 0;
for(int i = 0; i < length; i++){
if(dp[i] == -1) continue;
for(int n = 0; n < N; n++){
if(i & (1 << n)) continue;
int next = dp[i] + sticks[n];
if(next <= target) dp[i | (1 << n)] = next % target;
// dp[i | (1 << n)] =
}
}
if(dp[(1 << N)-1] == 0) cout << "yes";
else cout << "no";
// cout << dp[(1 << N)-1] << "\n";
cout << "\n";
}
return 0;
}
[BOJ] 막대 정사각형
https://compy07.github.io/Blog/posts/boj/4348/