1. 程式人生 > >hdu5375 Gray code(DP)

hdu5375 Gray code(DP)

style 就會 gray code tar har sof case ref pro

題目鏈接:

http://acm.hdu.edu.cn/showproblem.php?pid=5375


題目大意:給你一個二進制串,帶’?’的位置能夠由你來決定填’1’還是’0’,補充完整之後轉換成格雷碼表示,每個位置都有一個權值a[i],僅僅有格雷碼為’1’的位能夠加上權值,問你終於權值之和最大為多少。

格雷碼表示能夠百度一下,在這裏能夠通俗一點講:對於這麽一個串,假設i位置是1,那麽他後面的數就會變化(0變1、1變0),註意僅僅是看初始串。

比如:初始串為110,那麽改變以後則為101,而不是100。

思路:考慮用dp解決,dp[i][j]表示對於第i個位置取j時的最大分數(j取0或者1)。

那麽就有dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]);

dp[i][1]=max(dp[i-1][0]+a[i],dp[i-1][1]);

當j為?時,表明j可能為0或者1。那麽久兩者都考慮處理一遍。

註意初始化。

#include<stdio.h>
#include<math.h>
#include<string.h>
#define max(a,b) a>b?

a:b int dp[200005][2],a[200005]; int main() { int T,i,j,l,k,t=0; char s[200005],c[200005]; scanf("%d",&T); while(T--) { t++; scanf("%s",s); l=strlen(s); for(i=0;i<l;i++) c[i+1]=s[i]; for(i=1;i<=l;i++) scanf("%d",&a[i]); for(i=0;i<200005;i++) { dp[i][0]=-999999; dp[i][1]=-999999; } if(c[1]==‘0‘)dp[1][0]=0; if(c[1]==‘1‘)dp[1][1]=a[1]; if(c[1]==‘?‘){ dp[1][0]=0; dp[1][1]=a[1]; } for(i=2;i<=l;i++) { if(c[i]==‘0‘){ dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]); } if(c[i]==‘1‘){ dp[i][1]=max(dp[i-1][0]+a[i],dp[i-1][1]); } if(c[i]==‘?

‘){ dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]); dp[i][1]=max(dp[i-1][0]+a[i],dp[i-1][1]); } } printf("Case #%d: ",t); if(c[l]==‘0‘)printf("%d\n",dp[l][0]); else if(c[l]==‘1‘)printf("%d\n",dp[l][1]); else printf("%d\n",max(dp[l][0],dp[l][1])); } return 0; }



hdu5375 Gray code(DP)