zoukankan      html  css  js  c++  java
  • 挑战练习题2.3动态规划 poj3046 Ant Counting dp

    题目链接:

    http://poj.org/problem?id=3046

    题意:

    有T种蚂蚁,共A只。同一个种的蚂蚁长得一样,但是不同种的蚂蚁牙齿颜色不同。任取n只蚂蚁(S<=n<=B),求能组成几种集合?

    题解:

    dp[i][j] := 使用前i个种可以配出来j个的集合的个数。
    那么dp[0][0] = 1,不使用任何蚂蚁配出空集的个数为1。

    挑战P69页的优化(O(n^2))真TM不懂

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    #define MS(a) memset(a,0,sizeof(a))
    #define MP make_pair
    #define PB push_back
    const int INF = 0x3f3f3f3f;
    const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
    inline ll read(){
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //////////////////////////////////////////////////////////////////////////
    const int maxn = 1e5+10;
    const int mod = 1e6;
    
    int dp[1000][maxn];
    int a[maxn];
    
    int main(){
        int T,A,S,B;
        cin >> T >> A >> S >> B;
        for(int i=1; i<=A; i++){
            int x; cin >> x;
            ++a[x];
        }
    
        // dp[i][j] = dp[i-1][j]+dp[i][j-k]; 使用前i个家族可以配出来“元素个数为j”的集合的个数
    
        dp[0][0] = 1;
        int tot = 0;
        for(int i=1; i<=T; i++){
            tot += a[i];
            for(int j=0; j<=tot; j++){
                for(int k=0; k<=a[i] && j>=k; k++){
                    dp[i][j] = (dp[i][j]+dp[i-1][j-k])%mod;
                }
            }
        }
    
        ll ans = 0;
        for(int i=S; i<=B; i++)
            ans = (ans + dp[T][i])%mod;
    
        cout << ans << endl;
    
        return 0;
    }

    滚动优化

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 #define MS(a) memset(a,0,sizeof(a))
     7 #define MP make_pair
     8 #define PB push_back
     9 const int INF = 0x3f3f3f3f;
    10 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
    11 inline ll read(){
    12     ll x=0,f=1;char ch=getchar();
    13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 //////////////////////////////////////////////////////////////////////////
    18 const int maxn = 1e5+10;
    19 const int mod = 1e6;
    20 
    21 int dp[2][maxn];
    22 int a[maxn];
    23 
    24 int main(){
    25     int T,A,S,B;
    26     cin >> T >> A >> S >> B;
    27     for(int i=1; i<=A; i++){
    28         int x; cin >> x;
    29         ++a[x];
    30     }
    31 
    32     // dp[i][j] = dp[i-1][j]+dp[i][j-k]; 使用前i个家族可以配出来“元素个数为j”的集合的个数
    33 
    34     int now=0,pre=1;
    35     dp[now][0] = 1;
    36     int tot = 0;
    37     for(int i=1; i<=T; i++){
    38         tot += a[i];
    39         swap(now,pre);
    40         MS(dp[now]);
    41         for(int j=0; j<=tot; j++){
    42             for(int k=0; k<=a[i] && j>=k; k++){
    43                 dp[now][j] = (dp[now][j]+dp[pre][j-k])%mod;
    44             }
    45         }
    46     }
    47 
    48     ll ans = 0;
    49     for(int i=S; i<=B; i++)
    50         ans = (ans + dp[now][i])%mod;
    51 
    52     cout << ans << endl;
    53 
    54     return 0;
    55 }

    蜜汁优化: 我写了啥?

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 #define MS(a) memset(a,0,sizeof(a))
     7 #define MP make_pair
     8 #define PB push_back
     9 const int INF = 0x3f3f3f3f;
    10 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
    11 inline ll read(){
    12     ll x=0,f=1;char ch=getchar();
    13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 //////////////////////////////////////////////////////////////////////////
    18 const int maxn = 1e5+10;
    19 const int mod = 1e6;
    20 
    21 int dp[1005][maxn];
    22 int a[maxn];
    23 
    24 int main(){
    25     int T,A,S,B;
    26     cin >> T >> A >> S >> B;
    27     for(int i=1; i<=A; i++){
    28         int x; cin >> x;
    29         ++a[x];
    30     }
    31 
    32     for(int i=0; i<=T; i++)
    33         dp[i][0] = 1;
    34 
    35     for(int i=1; i<=T; i++){
    36         for(int j=1; j<=A; j++){
    37             if(j-1-a[i] >= 0)
    38                 dp[i][j] = (dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1-a[i]] + mod) % mod;
    39             else
    40                 dp[i][j] = (dp[i][j-1]+dp[i-1][j]) % mod;
    41         }
    42     }
    43 
    44     ll ans = 0;
    45     for(int i=S; i<=B; i++)
    46         ans = (ans + dp[T][i]) % mod;
    47     cout << ans << endl;
    48 
    49     return 0;
    50 }
  • 相关阅读:
    Java 设计模式——状态模式
    Java 设计模式——外观模式
    Java高级之虚拟机加载机制
    17.1.1.6 Creating a Data Snapshot Using Raw Data Files 创建一个数据快照使用 Raw Data Files
    17.1.1.5 Creating a Data Snapshot Using mysqldump
    17.1.1.4 Obtaining the Replication Master Binary Log Coordinates 得到复制master binary log 位置:
    17.1.1.3 Creating a User for Replication 创建一个用于用于复制:
    17.1.1.2 Setting the Replication Slave Configuration
    17.1.1.1 Setting the Replication Master Configuration 设置复制的master 配置:
    17.1.1 How to Set Up Replication 设置复制:
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827616.html
Copyright © 2011-2022 走看看