NBUT:魔法少女(動態規劃)
https://ac.2333.moe/Problem/view.xhtml?id=1010
- 問題描述
-
前些時間虛淵玄的鉅獻小圓著實火了一把。 在黑長直(小炎)往上爬樓去對抗魔女之夜時,她遇到了一個問題想請你幫忙。 因為魔女之夜是懸浮在半空的,所以她必須要爬樓,而那座廢墟一共有n層,而且每層高度不同,這造成小炎爬每層的時間也不同。不過當然,小炎會時間魔法,可以瞬間飛過一層或者兩層[即不耗時]。但每次瞬移的時候她都必須要至少往上再爬一層(在這個當兒補充魔力)才能再次使用瞬移。爬每單位高度需要消耗小炎1秒時間。 消滅魔女之夜是刻不容緩的,所以小炎想找你幫她找出一種最短時間方案能通往樓頂。
- 輸入
本題有多組資料,以檔案輸入結尾結束。
每組資料第一行一個數字N(1 <= N <= 10000),代表樓層數量。
接下去N行,每行一個數字H(1 <= H <= 100),代表本層的高度。
- 輸出
-
對於每組資料,輸出一行,一個數字S,代表通往樓頂所需的最短時間。
- 樣例輸入
-
5 3 5 1 8 4
- 樣例輸出
-
1
dp[i][0]表示走上i層,dp[i][1]表示飛上i層。
當走上i層的時候,是去i-1層加上去i層的時間,去i-1層又可以飛上去或者走上去,
所以dp[i][0]=min(dp[i-1][0],dp[i-1][1])+a[i];
飛上i層的時候可以從i-1層或者i-2層飛上去,
但是i-1或者i-2必須是走上去的,
所以dp[i][1]=min(dp[i-2][0],dp[i-1][0]);
#include<stdio.h> #include<string.h> #define N 10200 int a[N]; int dp[N][5]; int min(int a,int b) { return a<b?a:b; } int main() { int i,n; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&a[i]); dp[1][0]=a[1]; dp[1][1]=0; for(i=2;i<=n;i++) { dp[i][0]=min(dp[i-1][0],dp[i-1][1])+a[i]; dp[i][1]=min(dp[i-2][0],dp[i-1][0]); } printf("%d\n",min(dp[n][0],dp[n][1])); } return 0; }
[1011] 魔法少女II
- 問題描述
-
炎為了拯救小圓,不斷地穿梭在不同的時空之中。而與此同時,小圓所揹負的就越多,她的能力也就越強。而她所揹負的因果線將是上一次倒退時所揹負的加上次數的階乘。如一次就是f1 = 1!,兩次就是f2 = 2! + f1,三次則是f3 = 3! + f2。而我們所需要計算的則是在炎將時空倒退了n(1 <= n <= 10^6)次之後所小圓揹負的因果。當然,這個數字會很大,我們只需要將結果對1000000取模即可。
- 輸入
-
本題有多組資料,每組資料一個正整數n(1 <= n <= 10^6),以EOF結束。
- 輸出
-
對於一組資料,輸出一個答案,代表小圓所揹負因果值,模1000000。
- 樣例輸入
-
5 10
- 樣例輸出
-
153 37913
#include<stdio.h>
#include<string.h>
#define N 1000020
long long dp[N];
int main()
{
int i,n;
dp[1]=1;
long long sum=1;
for(i=2;i<N;i++)
{
sum=(sum*i)%1000000;
dp[i]=(dp[i-1]+sum)%1000000;
}
while(scanf("%d",&n)!=EOF)
{
printf("%d\n",dp[n]);
}
return 0;
}