zoukankan      html  css  js  c++  java
  • [hdu4713 Permutation]DP

    题意:将一个数拆成若干数的和使得它们的最小公倍数最大

    思路:一个数x可以拆成p1k1 + p2k2 + ... + pnkn形式,其中pi是质数或1。对于最小公倍数最大的情况,一定可以表示成这种形式。令dp[i][j]表示考虑前j个质数来构成i的最大公倍数,那么可以得到如下转移方程:

    dp[i][j]=max{dp[i][j-1],dp[i-k][j-1]*k},k=prime[j]t<=i

    用滚动数组计算dp数组,同时用一个数组来存具体方案,在dp值更新时更新具体方案。

     

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    #pragma comment(linker, "/STACK:10240000")
    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define X                   first
    #define Y                   second
    #define pb                  push_back
    #define mp                  make_pair
    #define all(a)              (a).begin(), (a).end()
    #define fillchar(a, x)      memset(a, x, sizeof(a))
    #define copy(a, b)          memcpy(a, b, sizeof(a))
    
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef unsigned long long ull;
    
    #ifndef ONLINE_JUDGE
    void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);}
    void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
    void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1;
    while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
    void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
    void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
    void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
    #endif
    template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
    template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
    
    const double PI = acos(-1.0);
    const int INF = 1e9 + 7;
    const double EPS = 1e-12;
    
    /* -------------------------------------------------------------------------------- */
    
    const int maxn = 1e4 + 7;
    
    vector<int> prime;
    vector<int> rst[maxn];
    int extra[maxn];
    bool vis[maxn];
    double dp[maxn];
    
    void getprimelist() {
        for (int i = 2; i < maxn; i ++) {
            if (!vis[i]) {
                prime.pb(i);
                for (ll j = (ll)i * i; j < maxn; j += i) {
                    vis[j] = true;
                }
            }
        }
    }
    
    void initdp() {
        for (int i = 0; i < maxn; i ++) dp[i] = 1.0;
        for (int j = 0; j < prime.size(); j ++) {
            for (int i = maxn - 1; i; i --) {
                for (ll k = prime[j]; k <= i; k *= prime[j]) {
                    if (umax(dp[i], dp[i - k] * k)) {
                        rst[i] = rst[i - k];
                        rst[i].pb(k);
                    }
                }
            }
        }
        for (int i = 1; i < maxn; i ++) {
            sort(all(rst[i]));
            extra[i] = i;
            for (int j = 0; j < rst[i].size(); j ++) {
                extra[i] -= rst[i][j];
            }
        }
    }
    
    void work(int n) {
        vector<int> ans;
        for (int i = 0; i < extra[n]; i ++) ans.pb(1);
        for (int i = 0; i < rst[n].size(); i ++) ans.pb(rst[n][i]);
        int start = 1;
        for (int i = 0; i < ans.size(); i ++) {
            for (int j = start + 1; j < start + ans[i]; j ++) printf("%d ", j);
            printf("%d%c", start, i == ans.size() - 1? '
    ' : ' ');
            start += ans[i];
        }
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
    #endif // ONLINE_JUDGE
        getprimelist();
        initdp();
        int T, n;
        cin >> T;
        while (T --) {
            cin >> n;
            work(n);
        }
        return 0;
    }
    
  • 相关阅读:
    爬虫之初试
    [已解决]疑问:关于postgres的to_number()
    随笔
    简单的任意列数均匀布局
    去除VS2010中中文注释下的红色波浪线
    DataTable举例
    DevExpress::XtraBars::BarEditItem获取EditValue值事件
    List<String^>^ 引用空间
    TreeList的VisibleNodesCount,Noes.Count,AllNdoesCount以及焦点节点的删除
    获取工程的exe文件的所在目录
  • 原文地址:https://www.cnblogs.com/jklongint/p/4744747.html
Copyright © 2011-2022 走看看