hdu1058 & hdu3199

这两题算同一类型,都是给你几个素数,问只能由这几个素数当做因子的数排列一下,第多少个是?
整体思想都是用已生成的序列是构造新的数。
hdu1058题意:一个数的因子只能是2,3,5,7 ,满足这样条件的数叫humble数,问第多少个是多少。
和紫书上一道丑数 题意近乎一模一样,开始做法就是用优先队列和set判重(后来发现也可以不需要借用set判重)

#include <fstream>
#include <iostream>
#include <string>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>
#include <memory.h>
#include <ctime>
#include <assert.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define eps 1e-8
#define M_PI 3.141592653589793

typedef long long ll;
const ll mod=1000000007;
const int inf=99999999;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

using namespace std;
priority_queue<ll,vector<ll>,greater<ll> >q;
set<ll>s;
ll a[]={2,3,5,7};
ll lst[8000];
void Solve()
{
    while(!q.empty())q.pop();
    q.push(1);
    s.insert(1);
    int t=0;
    while(t<=5942)
    {
        ll x=q.top();q.pop(); lst[t++]=x;
        for(int j=0;j<4;j++){
            ll num=x*a[j];
            if(!s.count(num)){
                s.insert(num);
                q.push(num);
            }
        }
    }
}

int main()
{
    Solve();
    int n;
    while(scanf("%d",&n)&&n){
        if(n%100==11||n%100==12||n%100==13)  printf("The %dth humble number is %lld.\n",n,lst[n-1]);
        else if(n%10==1) printf("The %dst humble number is %lld.\n",n,lst[n-1]);
        else if(n%10==2) printf("The %dnd humble number is %lld.\n",n,lst[n-1]);
        else if(n%10==3)   printf("The %drd humble number is %lld.\n",n,lst[n-1]);
        else printf("The %dth humble number is %lld.\n",n,lst[n-1]);
    }
}

这题还有一种思想是每次用选择生成的最小满足条件的数,加入集合,再判断这个数可以从集合里面那个数的下标转移过来,下标++。
体现有序数组的连续性。

#include<bits/stdc++.h>
#define min(a,b) (a<b?a:b)
#define min4(a,b,c,d) min(min(a,b),min(c,d))
using namespace std;
typedef long long ll;
ll dp[6000];
void init()
{
    dp[1]=1;
    int t=2;
    int p1=1,p2=1,p3=1,p4=1;
    while(t<=5842){
      dp[t++]=min4(dp[p1]*2,dp[p2]*3,dp[p3]*5,dp[p4]*7);
      if(dp[t-1]==dp[p1]*2) p1++;
      if(dp[t-1]==dp[p2]*3) p2++;
      if(dp[t-1]==dp[p3]*5) p3++;
      if(dp[t-1]==dp[p4]*7) p4++;
    }
}

int main()
{
    init();
    int n;while(scanf("%d",&n)&&n){
        if(n%100!=11&&n%10==1) printf("The %dst humble number is %lld.\n",n,dp[n]);
        else if(n%100!=12&&n%10==2) printf("The %dnd humble number is %lld.\n",n,dp[n]);
        else if(n%100!=13&&n%10==3) printf("The %drd humble number is %lld.\n",n,dp[n]);
        else printf("The %dth humble number is %lld.\n",n,dp[n]);
    }
}

hdu3199
类似的做法。

#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>
#include <memory.h>
#include <ctime>
#include <assert.h>

#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define eps 1e-8
#define M_PI 3.141592653589793

typedef long long ll;
const ll mod=1000000007;
const int inf=99999999;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

using namespace std;
ll dp[110000];
int n;
ll solve(ll a,ll b,ll c)
{
    memset(dp,0,sizeof(dp));
    dp[0]=1;
    int t=1,p1=0,p2=0,p3=0;
    while(t<=n+1)
    {
        dp[t++]=min(dp[p1]*a,min(dp[p2]*b,dp[p3]*c));
        if(dp[p1]*a==dp[t-1]) p1++;
        if(dp[p2]*b==dp[t-1]) p2++;
        if(dp[p3]*c==dp[t-1]) p3++;
    }
    return dp[n];
}

int main()
{
    ll a,b,c;
    while(~scanf("%lld %lld %lld %d",&a,&b,&c,&n)){
        printf("%lld\n",solve(a,b,c));
    }
}

你可能感兴趣的:(dp-STL)