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

dp+高精度 uva-10069-Distinct Subsequences

編輯:C++入門知識

      題目大意:   給兩個字符串A,B,求B串在A串中出現的個數。       解題思路:   dp+高精度。   dp[i][j][k]表示串B的前i個在串A的前j個中出現的個數,k表示位數,每一位表示4位十進制的數。   如果save2[i]==save1[j]  則dp[i][j]=dp[i][j-1]+dp[i-1][j-1]; 注意處理初始化的問題。   如果save2[i]!=save1[j]   則dp[i][j]=dp[i][j-1];   高精度:每一位表示4位十進制的數,如果一位一位的相加的話會超時。       代碼:   [cpp]   #include<iostream>   #include<cmath>   #include<cstdio>   #include<cstdlib>   #include<string>   #include<cstring>   #include<algorithm>   #include<vector>   #include<map>   #include<stack>   #include<queue>   #define eps 1e-6   #define INF (1<<20)   #define PI acos(-1.0)   using namespace std;      char save1[11000],save2[120];   int dp[120][11000][30];   //dp[i][j]表示Zi在Aj中一共有多少個  一位表示4位10000         void add(int i,int j)   {       int i1=i,j1=j-1,i2=i-1,j2=j-1;          for(int k=1;k<=30;k++)       {           dp[i][j][k+1]+=(dp[i1][j1][k]+dp[i2][j2][k])/10000; //進位           dp[i][j][k]+=(dp[i1][j1][k]+dp[i2][j2][k])%10000;       }       return ;   }      int main()   {       int ca;          scanf("%d",&ca);       while(ca--)       {           scanf("%s%s",save1,save2);              int len1=strlen(save1),len2=strlen(save2);              memset(dp,0,sizeof(dp));              for(int j=0;j<=len1;j++) //注意初始化,用於構建第一種情況               dp[0][j][1]=1;              for(int i=1;i<=len2;i++)               for(int j=1;j<=len1;j++)               {                   if(save2[i-1]==save1[j-1])                   {                       //dp[i][j]=dp[i][j-1]+dp[i-1][j-1]; //可以從dp[i][j-1]繼承過來,也可以新增dp[i-1][j-1]個                       add(i,j);                   }                   else                   {                       //dp[i][j]=dp[i][j-1];                       for(int k=1;k<=30;k++)  //直接復制                           dp[i][j][k]=dp[i][j-1][k];                      }               }           //printf("%lld\n",dp[len2][len1]);           int i;           for(i=30;dp[len2][len1][i]==0&&i>=1;i--)  //除掉前置零               ;           printf("%d",dp[len2][len1][i]); //把第一個處理,不用4位處理。           i--;           for(;i>=1;i--)               printf("%04d",dp[len2][len1][i]); //注意前置零           putchar('\n');       }       return 0;   }              

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