1. 程式人生 > >挑戰練習題2.3動態規劃 poj3046 Ant Counting dp

挑戰練習題2.3動態規劃 poj3046 Ant Counting dp

題目連結:

題意:

有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; }

滾動優化

#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[2][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”的集合的個數

    int now=0,pre=1;
    dp[now][0] = 1;
    int tot = 0;
    for(int i=1; i<=T; i++){
        tot += a[i];
        swap(now,pre);
        MS(dp[now]);
        for(int j=0; j<=tot; j++){
            for(int k=0; k<=a[i] && j>=k; k++){
                dp[now][j] = (dp[now][j]+dp[pre][j-k])%mod;
            }
        }
    }

    ll ans = 0;
    for(int i=S; i<=B; i++)
        ans = (ans + dp[now][i])%mod;

    cout << ans << endl;

    return 0;
}

蜜汁優化: 我寫了啥?

#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[1005][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];
    }

    for(int i=0; i<=T; i++)
        dp[i][0] = 1;

    for(int i=1; i<=T; i++){
        for(int j=1; j<=A; j++){
            if(j-1-a[i] >= 0)
                dp[i][j] = (dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1-a[i]] + mod) % mod;
            else
                dp[i][j] = (dp[i][j-1]+dp[i-1][j]) % mod;
        }
    }

    ll ans = 0;
    for(int i=S; i<=B; i++)
        ans = (ans + dp[T][i]) % mod;
    cout << ans << endl;

    return 0;
}

相關推薦

挑戰練習題2.3動態規劃 poj3046 Ant Counting dp

題目連結: 題意: 有T種螞蟻,共A只。同一個種的螞蟻長得一樣,但是不同種的螞蟻牙齒顏色不同。任取n只螞蟻(S<=n<=B),求能組成幾種集合? 題解: dp[i][j] := 使用前i個種可以配出來j個的集合的個數。 那麼dp[0][

POJ3046 Ant Counting DP 隔板法講解 有圖有真相

Bessie was poking around the ant hill one day watching the ants march to and fro while gathering food. She realized that many of the ants were siblings, in

2.3 動態空間管理

動態空間 操作系統 nbsp 強烈 系統 期望 sun cto i++ 空間管理方法主要分為兩類:靜態的和動態的。顧名思義,靜態空間管理即是在向量生命期內,其內部數組所占物理空間的容量不允許增加,這種策略既拘泥固化且空間管理效率底下,因此常采取動態空間管理策略,具體方法是使

挑戰程式設計 初級篇 動態規劃

1.01揹包問題 1.樸素的二維陣列解法 dp[i][j]表示前i件物品裝入容量是j的揹包所能獲得的最大價值 狀態轉移方程是dp[i][j]=(1)dp[i-1][j](在第i件物品裝不下的情況下) (2)max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])(裝的下的情況下,裝和不

資訊保安練習題 2-3

1. 防火牆作為一種被廣泛使用的網路安全防禦技術,其自身有一些限制,它不能阻止 (A)A. 內部威脅和病毒威脅B. 外部攻擊C. 外部攻擊、外部威脅和病毒威脅D. 外部攻擊和外部威脅解析:防火牆是一種位於內部網路與外部網路之間的網路安全系統,內外網路通訊時,依照特定的規則,允許或是限制傳輸的資料通過。它不能防

動態規劃(2):動態規劃的三種形式

例:數字三角形(POJ 1163) Language:DefaultThe Triangle Time Limit: 1000MSMemory Limit: 10000KTotal Submissions: 45053Accepted: 27208Des

NOI 2.6 動態規劃 1996:登山

題目來源:http://noi.openjudge.cn/ch0206/1996/1996:登山總時間限制: 5000ms   記憶體限制: 131072kB描述五一到了,PKU-ACM隊組織大家去登山觀光,隊員們發現山上一個有N個景點,並且決定按照順序來瀏覽這些景點,即每次

NOI 2.6 動態規劃 7625:三角形最佳路徑問題

題目來源:http://noi.openjudge.cn/ch0206/7625/7625:三角形最佳路徑問題總時間限制: 1000ms    記憶體限制: 65536kB描述如下所示的由正整數數字構成的三角形: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 從

thinkphp3.2.3動態切換多資料庫

版本說明: thinkphp3.2.3新增自定義行為類 檔案位置:Application/Common/Behaviors/SwitchDbBehavior.class.php 檔案內容: namespace Common\Behaviors; class SwitchDbBehavior { //私

精通Flex 3.0――4.2.3 動態新增按鈕——SimpleButton類

SimpleButton類作用如名字一樣,表示一個簡單按鈕類。通過定義一個SimpleButton類,可以建立一個使用者互動的按鈕。SimpleButton用於處理使用者互動。而SimpleButton的顯示是與SimpleButton的處理過程分離的。這樣,可以使用相同的處

[bzoj2748][HAOI2012]音量調節_動態規劃_背包dp

sound $1 IV sans 代碼 ace 更新 () highlight 音量調節 bzoj-2748 HAOI-2012 題目大意:有一個初值,給你n個$\delta$值,求最後不超過給定的限制的情況下的改變的最大值。每個$\delta$值可以+也可以-。 註釋

[bzoj1195][HNOI2006]最短母串_動態規劃_狀壓dp

字典 數據 n) 求一個 表示 n! 規劃 esp zoj 最短母串 bzoj-1195 HNOI-2006 題目大意:給一個包含n個字符串的字符集,求一個字典序最小的字符串使得字符集中所有的串都是該串的子串。 註釋:$1\le n\le 12$,$1\le max l

動態規劃練習——UVa10003——區間dp

題目連結:https://vjudge.net/contest/232313#problem/I 紫書上的動態規劃例題,很明顯是一個區間線性規劃的問題,想起之前做過的矩陣鏈乘,這題和它很像,列舉方向都是向j-i遞增的 方向,這裡有個大神的區間dp模板的總結:http://www.cnblog

動態規劃之狀態壓縮dp入門

狀態壓縮動態規劃(簡稱狀壓dp)是另一類非常典型的動態規劃,通常使用在NP問題的小規模求解中,雖然是指數級別的複雜度,但速度比搜尋快,其思想非常值得借鑑。 為了更好的理解狀壓dp,首先介紹位運算相關的知識。 1.’&’符號,x&y,會將兩個十進位制數在二進位

2019.01.02 poj3046 Ant Counting(生成函式+dp

傳送門 生成函式基礎題。 題意:給出 n n n個數以及它們的數量,求從所有數中選出

動態規劃學習系列——區間DP(二)

上一篇我們看了區間型DP的一道經典入門題——石子歸併,這一次同樣是類似的一道題——石子歸併2 題目連結:wikioi 2102 題幹不同之處在於,現在我們的石子不是排成一列了,而是圍成一個環,我們要怎麼把問題轉化成普通的石子歸併呢? 其實這是一種挺常見的演

Ant Counting--(DP)

SOS!!! 題意:螞蟻們來自3個家庭,每個家庭內部成員一個樣,不同家庭不一樣。從裡面選s個,能有幾種組合,選b個有幾種組合。s的組合數加上b的組合數。 我看的題解是分組揹包(有些疑問) 先上程式碼 #include <iostream> #incl

POJ 3046 Ant Counting(dp—多重集組合數問題)

 Ant Counting Time Limit:1000MS Memory Limit:65536K Total Submissions:3753 Accepted:1475

演算法優化:動態規劃加速,貨物運輸問題,四邊形不等式, 從O(n^2)到O(n^3)

貨物運輸問題 遞迴方程為: 更為一般形式的遞迴方程 看起來是不是像可以使用分治的策略實現,但是min裡面子問題太多了,只能使用動態規劃的招了。 i,j是什麼含義了?動態規劃裡i,j都是指的是問題規模,對應到貨物運輸問題指的是什麼了?我們從數學上理解i,j是指

2-3-配置DHCP服務器實現動態地址分配

客戶端 -name sci oom 動態分配 工作站 request請求 負責 evel 學習一個服務的過程: 1、 此服務的概述:名字,功能,特點,端口號 2、 安裝 3、 配置文件的位置 4、 服務啟動關閉腳本,查看端口 5、 此服務的使用方法 6、 修