程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> nefu 642 monkey

nefu 642 monkey

編輯:C++入門知識

題目:大意是說 有n個台子,編號1-n,開始時,有一只猴子站在編號1的台子上,猴子可以自由地蹦到兩側的台子上,每次i移動話費的時間是一秒,有個人每秒鐘仍一個盤子到其中的一個台子上,問在猴子移動次數不超過t的情況下,猴子能接到的最多的盤子數。

方法:一個dp的題目,原來看到過,還不會做,直到最近在做dp的題目,才解決了這個題目。

使用一個三維數組dp[i][j][k],i代表當前進行到第i秒鐘,也是第i盤子扔出的時間,j代表當前移動的步數,k代表當前所處的台子編號。

很容易能找到狀態轉移方程:dp[i][j][k]=max(dp[i-1][j][k],max(dp[i-1][j-1][k-1]),dp[i-1][j-1][k+1])+(f[i]==k);

當然本題的f[i]是有相應的值的,需要在進行一下處理。

已經找到了狀態轉移方程之後,還有一些要注意的問題就是需要進行一下限制,比如:題目中已經說到了猴子的初始位置是一號台子,而不是隨意的,所以這裡就需要注意了,當進行到第i個盤子的時候,假設j>i,從一開始到此時猴子的移動范圍為1-i+1這幾個台子,所以要加一個限制條件了,因為這個錯了n次。

代碼:

#include 
#include 
#include 
using namespace std;
struct node
{
    int d,v;
}z[105];
int dp[105][105][105];
int main()
{
     int n,m,t,sum=1;
     int i,j,k;
     while(scanf("%d%d%d",&n,&m,&t)!=EOF)
     {
         int mas=0;
         memset(dp,0,sizeof(dp));
         for(i=1;i<=m;i++)
            scanf("%d%d",&z[i].d,&z[i].v);
          t++;
         for(i=1;i<=m;i++)
         for(j=1;j<=t&&j<=i+1;j++)   //這裡加了限制,還有為了方便dp數組中j-1不使得數組越界,我把移動次數用1代表0,2代表1...這也是為什麼上面t++
         for(k=1;k<=n&&k<=j;k++)     //k>j就沒必要更新了
         {
                 dp[i][j][k]=max(dp[i-1][j][k],max(dp[i-1][j-1][k-1],dp[i-1][j-1][k+1]));
                 if(z[i].d==k) dp[i][j][k]+=z[i].v;
                 if(mas

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved