一道題DP

來源:互聯網
上載者:User

標籤:des   style   blog   color   os   for   

Problem Description小明明又被大威魚抓住了,大威魚把小明明關在地牢裡,地牢由n * n 個房間組成,小明被困在地牢的最左上方的房間中,出口在最右下角,他想逃出這個詭異的地牢,但是他只能向下或者向右走。
小明每經過一個房間,都要受到一定的傷害(傷害都大於0),而且這個傷害可不是累加的哦,是累乘的,因此當他走出地牢的時候,他受到的傷害會非常大。但是小明有一個終極技能,能把受到的傷害X轉變為金幣,轉化如下。
int val(type x) {
  int ret = 0;
  while(x % 12 == 0) {
    x /= 12;
    ret++;
  }
  return ret;
}
請問小明最多能得到多少金幣?Input輸入包含多組測試案例,每組測試案例的第一行是一個整數n(n <= 50),接下來n行每行n個正整數 (<= 10 ^ 9) 表示每個房間對小名造成的傷害,當n = 0 時輸入結束。Output先輸出Case,Case數從1開始,再輸出小明獲得的最大金幣,具體輸出形式見範例。Sample Input
312 1 246 3 44 4 160
Sample Output
Case #1: 3
解析:
12可以分為2*2*3;
那麼答案就是統計min(2的個數/2,3的個數)的最大值;
如果直接記錄2的個數,3的個數為狀態的話,50*50*乘積中2的冪次*3的冪次,記憶體不夠。
於是想到只將3的冪次作為一種狀態,然後記錄沿途能達到的2的個數。
狀態方程

F[I][J][K]表示能夠有2因子的個數,沒有就為-1;
Temp=max(F[I-1][J][K],F[I]J-1][K]);
F[I][J][K+MP[I][J].Y]=TEMP+MP[I][J].X;
注意邊界;
具體看代碼了;
#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<vector>#include<set>#include<map>#define INF 999999999#define N   100000using namespace std;struct node{    int x,y;}mp[51][51];int dp[51][51][2000];int main(){     int t=0;     int n;       while (scanf("%d",&n)!=EOF&&n){            printf("Case #%d: ",++t);            memset(mp,0,sizeof(mp));            memset(dp,-1,sizeof(dp));//初始化為-1,                       for (int i=1;i<=n;i++)            for (int j=1;j<=n;j++)            {                int xx,yy;                scanf("%d",&xx);                yy=xx;                while (yy%2==0)//記錄元素是2的多少次方                {                 mp[i][j].x++;                 yy/=2;                }                while (xx%3==0)記錄元素是3的多少次放                {                    mp[i][j].y++;                    xx/=3;                }            }            dp[0][0][0]=0;            for (int i=1;i<=n;i++) dp[0][i][0]=0,dp[i][0][0]=0;//邊界                      for (int i=1;i<=n;i++)//狀態轉移             for (int j=1;j<=n;j++)               for (int k=0;k<=1200;k++)//1200是自己隨便寫的一個狀態,可能實際沒有這麼多               {                  int temp=max(dp[i-1][j][k],dp[i][j-1][k]);//考慮DP[I-1][J][K],DP[I][J-1][K]都可能為-1                  if (temp>-1)                  dp[i][j][k+mp[i][j].y]=mp[i][j].x+temp;               }        int ans=0;        for (int i=0;i<=1200;i++)        ans=max(ans,min(dp[n][n][i]/2,i));        printf("%d\n",ans);     }    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.