1. 程式人生 > >NBUT:魔法少女(動態規劃)

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