Codeforces Round #197 (Div. 2): C. Xenia and Weights(記憶化搜尋)
阿新 • • 發佈:2018-11-10
題意:
先輸入一個長度為10的01串,第i個數字為1表示你有重量為i的砝碼無數個,第i個數字為0表示你沒有重量為i的砝碼,你需要按照以下規則在一個一開始平衡的天平上放上m個砝碼
- 第1個砝碼放在天平左邊,第2個砝碼放在天平的右邊,第3個砝碼放在天平左邊……依次交替,直到放完m個
- 每次放完砝碼後,必須滿足天平往當前這一側傾斜(重量大於另一側)
- 不能連續放兩次相同質量的砝碼
求出任意一組合法解,如果沒有輸出NO
思路:
dp[m][last][val]表示當前已經放了m個砝碼,上一次放的砝碼質量為last,且放完後天平的不平衡度為val的狀態是否已經搜過
搜出一組解就直接在DFS時輸出,搜不到就輸出NO
複雜度O(10*10*m)
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<string> #include<math.h> #include<queue> #include<stack> #include<iostream> using namespace std; #define LL long long #define mod 1000000007 int flag[12], dp[1005][12][12]; int Sech(int n, int last, int dis) { int i; if(dp[n][last][dis]) return 0; dp[n][last][dis] = 1; if(n==1) { if(last==dis) { printf("YES\n%d", last); return 1; } return 0; } if(dis>=last || dis==0) return 0; for(i=1;i<=10;i++) { if(flag[i]==0 || last==i) continue; if(Sech(n-1, i, last-dis)) { printf(" %d", last); return 1; } } return 0; } int main(void) { int i, n, j; for(i=1;i<=10;i++) scanf("%1d", &flag[i]); scanf("%d", &n); for(i=1;i<=10;i++) { if(flag[i]==0) continue; for(j=0;j<=i;j++) { if(Sech(n, i, j)) { puts(""); return 0; } } } printf("NO\n"); return 0; }