[HNOI2006]鬼谷子的钱袋
这题学过多重背包二进制优化都知道用二进制拆分就行,然而题中说两数不能相同,比如9,拆分后就是1 2 2 4,不符合,所以遇到a[i] == a[i + 1] 的情况,就a[i]--,a[i + 1]++就行。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<stack> 8 #include<queue> 9 #include<vector> 10 #include<cctype> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps = 1e-8; 19 const int maxn = 105; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) putchar('-'), x = -x; 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 ll m, cnt, a[maxn]; 37 38 int main() 39 { 40 m = read(); 41 ll x = 1; 42 while(m - x > 0) 43 { 44 m -= x; 45 a[++cnt] = x; 46 x <<= 1; 47 } 48 a[++cnt] = m; 49 write(cnt); enter; 50 sort(a + 1, a + cnt + 1); 51 for(int i = 1; i <= cnt; ++i) 52 { 53 if(a[i] == a[i + 1] && a[i] != 1) a[i]--, a[i + 1]++; 54 write(a[i]); space; 55 } 56 enter; 57 }