1. 程式人生 > >簡單dp&遞推合集

簡單dp&遞推合集

以下題目全部來自EOJ。

1075 慶祝迎評成功

一個蛋糕切n刀,求最多可以切成幾塊。

說明

對三維問題,降維處理不失為一種好方法。我們先考慮二維情況:

  • n條直線分割一個平面,最多可以分割成幾塊?

假設n-1條直線已經確定(並且已經是最優解,下同),那麼第n條直線需要與前n-1條直線交於n-1個不同的點,這使第n條直線被分為n份,平面則將被多分出n個區域。

我們設二維情況的答案為f(n),則f(n)=f(n-1)+n,推得通項公式f(n)=1+n(n+1)/2。

推廣到三維,設此時答案為s(n)。n-1個平面已經確定,第n個平面需要與前n-1個平面有n-1條交線,這使第n個平面被分為f(n-1)份,空間則將被多分出f(n-1)個區域。我們得到:s(n)=s(n-1)+f(n-1)=s(n-1)+1+n(n-1)/2。

邊界條件為s(0)=1。

#include <stdio.h>

int main(){
    int a, i;
    long long s[1001];
    s[0] = 1;
    for (i = 1; i < 1001; ++i)
        s[i] = s[i - 1] + i * (i - 1) / 2 + 1;
    while (scanf("%d", &a) && a)
        printf("%lld\n", s[a]);
    return 0;
}

1015 核電站

一個核電站有 N 個放核物質的坑,坑排列在一條直線上。

如果連續 M 個坑中放入核物質,則會發生爆炸,於是,在某些坑中可能不放核物質。

任務:對於給定的 N 和 M,求不發生爆炸的放置核物質的方案總數

說明

設第n個坑不發生爆炸的方案數為f(n),我們假設前n-1個坑已經確定。分兩種情況:

  1. 已經有連續m-1個核物質,那麼第n個坑只能不放核物質,且這m-1個坑前的那個坑也不能放核物質。方案數為f((n-1)-(m-1)-1)=f(n-m-1)。
  2. 否則,第n個坑可以選擇放或不放。方案數為2*[f(n-1)-f(n-m-1)]。

邊界條件f(0)=1。

具體計算時可以用dp的遞推形式寫,也可以像如下程式碼中用2的冪計算:

#include <stdio.h>
#include <math.h> int main(void) { int n, m, i; long long nuc[60]; nuc[0] = 1; while (~scanf("%d%d", &n, &m)){ for (i = 1; i <= 50; ++i){ if (i < m) nuc[i] = (long long)pow(2, i); else if(i == m) nuc[i] = (long long)pow(2, m) - 1; else nuc[i] = 2 * nuc[i - 1] - nuc[i - m - 1]; } printf("%I64d\n", nuc[n]); } return 0; }

(注:這裡不能預處理nuc陣列,因為m未知)

3267 足球錦標賽

計分板上的每一位都按順序掛了 0 到 9 這 10 個牌子,所以可以表示 000 至 999。當其中一個隊的得分從 010 變成 011 時,計分員只要將最後一位的最前面的牌子向後翻即可,共需翻動一塊牌子;當得分從 019 變成 020 是,由於 9 後面已經沒有牌子了,所以計分員要將 0 到 9 全部翻到前面,並將倒數第二位的牌子 1 翻到後面,所以共需翻動 10 塊牌子。

現場的計分牌和圖中所示還是存在差異的,現場的計分牌會很大,很重,所以翻每塊牌子都要消耗 1 點體力。

你是計分員,現在比賽還剩下最後十分鐘。現在有一個預言家告訴你在這十分鐘裡,雙方得分共計多少;但他沒有告訴你雙方得分各是多少。所以你想要知道你要花費的體力值最多是多少。

說明

先模擬翻牌,預處理記錄體力的陣列。然後列舉雙方得分情況,求最大值。

#include <stdio.h>

int dp[1001]={0};

void init()
{
    int i;
    for (i = 1; i <= 999; ++i){
        if (i % 100 == 0) dp[i] = dp[i - 1] + 19;
        else if (i % 10 == 0) dp[i] = dp[i - 1] + 10;
        else dp[i] = dp[i - 1] + 1;
    }
    return;
}

int main(void)
{
    int t, i, a, b, sc, j;
    scanf("%d", &t);
    init();
    for (i = 1; i <= t; ++i){
        scanf("%3d %3d %d", &a, &b, &sc);
        int ans = 0, now = 0;
        for (j = 0; j <= sc; ++j){
            now = dp[a + j] - dp[a] + dp[b + sc - j] - dp[b];
            if (now > ans) ans = now;
        }
        printf("Case %d: %d\n", i, ans);
    }
    return 0;
}

1052 0-1揹包問題

已知 n 個物體 1,2,3,…,n 與一個揹包。物體 i 的重量為 Wi>0,價值為 Pi>0 (i=1,2,…,n),揹包容量為 M>0。

求在不超過揹包容量的情況下,使得裝進去的物體的價值最高。

說明

經典入門dp題。用一維陣列實現時需要注意j需要從m到w遞減,這與動規的bottom-up思路是一致的。

#include<stdio.h>

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n, m, i, j, w, v, a[100001] = {0};
        scanf("%d%d", &n, &m);
        for(i = 0; i < n; ++i){
            scanf("%d%d", &w, &v);
            for(j = m; j >= w; --j)
                if (a[j - w] + v > a[j]) a[j] = a[j - w] + v;
        }
        printf("%d\n",a[m]);
    }
    return 0;
}

3302 列印

列印 n 個相同的字元,插入或刪除一個字元花費的時間為 x,複製當前整個文字並且貼上在後面的時間花費為 y,求完成 n 個字元的列印所需的最小花費時間。

說明

dp[i]表示列印i個字元需要的最小時間。

  1. i為偶數時,可能是(i-1個字元+插入一個字元)/(i/2個字元複製一次)兩種操作之一產生的,取它們的最小值。
  2. i為奇數時,可能是(i-1個字元+插入一個字元)/((i+1)/2個字元複製一次)兩種操作之一產生的,取它們的最小值。

寫的時候用的c,還並不會定義巨集,導致程式碼看起來比較繁瑣。

#include <stdio.h>
#include <memory.h>
#define MAX 10000001
typedef long long LL;

LL dp[MAX];

LL printing(int n, int x, int y)
{
    int i;
    if (n == 0) return 0;
    if (n == 1) return x;
    memset(dp, 0, sizeof(dp));
    for (i = 1; i <= n; ++i){
        if (i % 2)
            dp[i] = (dp[i-1]+x < dp[(i+1)/2]+y+x)?dp[i-1]+x:dp[(i+1)/2]+y+x;
        else
            dp[i] = (dp[i-1]+x < dp[i/2]+y)?dp[i-1]+x:dp[i/2]+y;
    }
    return dp[n];
}

int main()
{
    int n,x,y;
    scanf("%d%d%d",&n, &x, &y);
    LL ans = printing(n, x, y);
    printf("%lld", ans);
    return 0;
}

相關推薦

簡單dp&

以下題目全部來自EOJ。 1075 慶祝迎評成功 一個蛋糕切n刀,求最多可以切成幾塊。 說明 對三維問題,降維處理不失為一種好方法。我們先考慮二維情況: n條直線分割一個平面,最多可以分割成幾塊? 假設n-1條直線已經確定(並且已

POJ 3786 dp- Adjacent Bit Counts *

num new red rip int chosen star program http Adjacent Bit Counts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 599

poj1163 - DP歸寫法

end calculate base main blog can idt integer field 本題超鏈接:http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS Memory Limi

HDU 2154 跳舞毯 | DP | | 規律

輸入 tom bcb win stream stl 也有 輸出 由於 Description 由於長期缺乏運動,小黑發現自己的身材臃腫了許多,於是他想健身,更準確地說是減肥。 小黑買來一塊圓形的毯子,把它們分成三等分,分別標上A,B,C,稱之為“跳舞毯”,他的運動方

Codeforces Round #455 (Div. 2) C. Python Indentation dp

air 方式 gpo pac sin -s font its 多少 Codeforces Round #455 (Div. 2) C. Python Indentation 題意:python 裏面,給出 n 個 for 循環或陳述語句,‘f‘ 裏面必須要有語句。按 p

題解——[NOI2009]管道取珠 DP +

通過 include for 使用 可能 update freopen 滾動 我們 ~~~題面~~~ 思路: 非常神的一道題,,,, 主要難點在思路的轉化, 不能看見要求sigam(a[i]^2)就想著求a[i], 我們可以對其進行某種意義上的拆分,即a[i]實際上可以代表

Java一些簡單的計算題

date rgs 日期格式 spa ram == int ner ng- 1、3個白球 3個紅球 6個黑球 隨機拿出8個球,算出所有結果 public class Ball{ public static void main(String[] args){

2018 “百度之星”程序設計大賽 - 初賽(A)1004 / hdu6377 度度熊看球賽 dp

的確 就會 世界杯 .cn 世界 problem 產生 amp 表示 度度熊看球賽 Problem Description 世界杯正如火如荼地開展!度度熊來到了一家酒吧。 有 N 對情侶相約一起看世界杯,熒幕前正好有 2×N 個橫排的位置。 所有人都會隨機坐在某個位置上。

Shell Necklace (dp改cdq分治 + fft)

mage class shell space 影響 set mod 技術分享 src 首先讀出題意,然後發現這是一道DP,我們可以獲得遞推式為 然後就知道,不行啊,時間復雜度為O(n2),然後又可以根據遞推式看出這裏面可以拆解成多項式乘法,但是即使用了fft,我們還需要做

CF 570E dp

題意:給一個n*m的小寫字母地圖,找從(1,1)到(n,m)點非升路徑,且路徑組成的字串是迴文串的路徑個數。 思路: 考慮從兩端同時走,然後在中間相遇,走的步數是確定的,為n+m-1, 所以只要兩邊同時走(n+m)/2步就行; 考慮dp遞推,只要條件限制好,是可以遞推的 設d

Bookshelf 2(poj3628,01揹包,dp) 對01揹包的分析與理解(圖文)

題目連結:Bookshelf 2(點選進入) 題目解讀: 給n頭牛,給出每個牛的高度h[i],給出一個書架的高度b(所有牛的高度相加>書架高度b),現在把一些牛疊起來(每頭牛隻能用一次,但不同的牛可能身高相同),在這些疊起來的牛的總高度>書架b的基礎上,找出最小的差距(由於輸入的資料會保證所有

諸侯安置 簡單

諸侯安置 Problem Description 很久以前,有一個強大的帝國,它的國土呈正方形狀(轉45度看),如圖所示。 這個國家有若干諸侯。由於這些諸侯都曾立下赫赫戰功,國王準備給他們每人一塊封地(正方形中的一格)。但是,這些諸侯又非常好戰,當兩個諸侯位於同一行或同一列時,

codeforce404 D. Minesweeper 1D DP

給定一個一維矩陣,其中包含‘1’、‘2’、‘0’、‘*’、‘?’,掃雷小遊戲——1表示左右有一個雷,2表示左右都有雷,0表示左右都沒有雷,*表示雷,?表示未知,求其中有多少種可能的情況,若該圖自相矛盾也輸出0 表示檔期位置為L,當前位置若是雷則為1,否則為0,下一位置若是雷

CodeForces 372B 腦洞大開的DP

題目: 做了兩個多小時,腦洞大開,給了一個01矩陣,求以a,b,為左上角,c,d為右下角的矩陣內有多少包含部分全為0的子矩陣 對於這道題目,一開始就想到了DP遞推,感覺而已,雖然準,可是做不出啊,想好

hdu6170-多看幾遍之DP&&字串-Two strings

http://acm.hdu.edu.cn/showproblem.php?pid=6170 給定兩個串。 a串是正常串。 b串中有兩種元素。 1 種是* ,可以讓前面那個出現任意次(甚至讓他出

Two strings hdu6170 dp

題意:給出兩個字串,第一個字串只包含小寫或者大寫字母,第二個字串包含小寫或者大寫字母或者特殊字元“.”和“*”,這裡“.”可以替換為任意字元,但是不能變成空。 這裡“a*”可以變成空串,可以變成a,也

牛客練習賽37-筱瑪的字符串-DP

c++ 要求 gree else if \n long long 根據 表示 pre 筱瑪的字符串 思路 :dp [ i ] [ j ] [ 3 ] 分別代表到第 i 位時 左括號比右括號多 j ,後面有三個狀態 分別表示當前位置 S3的字符 是正在反轉的,還是 反轉完成的

bzoj1026-windy數-數位DP-寫法與迴寫法

(有任何問題歡迎留言或私聊 && 歡迎交流討論哦 題意:傳送門  原題目描述在最下面。  windy定義了一種windy數。不含前導零且相鄰兩個數字之差至少為2的正整數被稱為windy數。 windy想知道,在A和B之間,包括A和B

URAL 1260 Nudnik Photographer 簡單

給出N個數,分別是1,2,3 . . . . . .N,然後回答按照兩項規則排列這N個數的方案數。 1,兩個相鄰的數的差不能超過2。 2,1必須放在第一個位置。 思路:對於第 n 個數的放置方案其實只需考慮 (n-1) 和 (n-2) 的情況。 1,(n-1)和(n-2)

BZOJ4321queue2——DP/

pan bsp scanf zoj 排列 name d+ 多少 ++ 題目描述 n 個沙茶,被編號 1~n。排完隊之後,每個沙茶希望,自己的相鄰的兩 人只要無一個人的編號和自己的編號相差為 1(+1 或-1)就行; 現在想知道,存在多少方案滿足沙茶們如此不苛刻的