Backward Digit Sums - POJ 3187 - Virtual Judge
由题意可知该题类似于杨辉三角求组合数,根据题意先把三角形的第n层求出来,然后再1到n用c++STL的next_permutation求出1到n的全排列,然后求最先出现的且使得数列最终求和等于sum的数列输出,根据杨辉三角的特点,可以看出最后一个数是由最初的数相邻两数的和不断相加得到,那么可以直接求出每个位置的数的贡献即可,即b[i]*a[n][i]
AC代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) //#pragma GCC optimize("Ofast") #include <iostream> #include <queue> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <cctype> #include <map> #include <vector> #include <set> #include <stack> #include <numeric> #include <iomanip> using namespace std; #define lowbit(x) ((x) & -(x)) #define IOS1 ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); #define IOS2 ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); typedef vector<int> vi; typedef vector<long long> vll; typedef vector<char> vc; template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; } const int INF = 0x3f3f3f3f; const int mod = 1000000007; int a[15][15], b[15]; void solve() { int n, sum; cin >> n >> sum; if (n == 1) { cout << sum << endl; } else { a[1][1] = 1; for (int i = 2; i <= n; i++) { for (int j = 1; j <= i; j++) { a[i][j] = a[i - 1][j] + a[i - 1][j - 1]; } } for (int i = 1; i <= n; i++) { b[i] = i; } int ans; do { ans = 0; for (int i = 1; i <= n; i++) { ans += b[i] * a[n][i]; } if (ans == sum) { for (int i = 1; i <= n; i++) { cout << b[i] << " \n"[i == n]; } break; } } while (next_permutation(b + 1, b + 1 + n)); } return; } int main() { //IOS1; IOS2; int __t = 1; //cin >> __t; for (int _t = 1; _t <= __t; _t++) { solve(); } return 0; } /* */
Backward Digit Sums(组合数,全排列)
最新推荐文章于 2022-12-27 20:50:20 发布