两个问题类似的dp,二者有时间复杂度的不同

1.https://vjudge.net/problem/POJ-2229/origin(这个问题是以2的倍数为物品的背包)

1

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
//#define int long long
#define N 1000005
using namespace std;
int w[N];
int dp[N];
int n,ans=0;
int main()
{
    scanf("%d",&n);
    for(int i=0;(1<<i)<=n;i++)
    {
        w[ans++]=(1<<i);
    }
    dp[0]=1;
    for(int i=0;i<ans;i++)
        for(int j=w[i];j<=n;j++)
        {
            dp[j]=(dp[j]+dp[j-w[i]])%1000000000;
        }
    printf("%d\n",dp[n]);
    return 0;
}

2.https://codeforces.com/contest/1673/problem/C(这个是以回文数为物品的背包)

2
 #include<bits/stdc++.h>
#define int unsigned long long
#define N 1000005
const int P=40004;
const int Q=502;
using namespace std;
int dp[P][Q];
int n;
int pan(int x)
{
    if(x/10000!=0)
    {
        int a=x/10000,b=x%10000/1000,d=x%100/10,f=x%10;
        if(a==f&&b==d)return 1;
        else return 0;
    }
    else if(x/10000==0&&x/1000!=0)
    {
        int a=x/1000,b=x%1000/100,c=x%100/10,d=x%10;
        if(a==d&&b==c)return 1;
        else return 0;
    }
    else if(x/1000==0&&x/100!=0)
    {
        int a=x/100,c=x%10;
        if(a==c)return 1;
        else return 0;
    }
    else if(x/100==0&&x/10!=0)
    {
        int a=x/10,b=x%10;
        if(a==b)return 1;
        else return 0;
    }
    else return 1;
}
signed main()
{
    vector<int>w;
    w.push_back(0);
    for(int i=1;i<=2*P;i++)
        if(pan(i))w.push_back(i);
    for(int j=1;j<=502;j++)
    {
        dp[0][j]=1;
    }
    for(int i=1;i<P;i++)
    {
        dp[i][0]=0;
        for(int j=1;j<=502;j++)
        {
            if(w[j]<=i)dp[i][j]=(dp[i][j-1]+dp[i-w[j]][j])%1000000007;
                //DP[k][m]=DP[k][m-1]+DP[k-p(m)][m],其中p(m)是第m个回文数
            else dp[i][j]=dp[i][j-1];
        }
    }
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--) {
        cin>>n;
        cout << dp[n][501] % 1000000007 << endl;
    }
    return 0;
}
posted @ 2024-05-10 17:41  伊芙加登  阅读(4)  评论(0编辑  收藏  举报