题意:一个01序列,改变第k位的条件是第k-1位是1并且前k-2位全是0,求使01序列全变成0的最小步骤。
题解:通过举几个使00...1变成00...0的例子可以发现,长度为i最后一位为1的最小步骤实际就是它的(2^i)-1,于是dp[i][0]代表前i位全为0的最小代价,dp[i][1]代表前i-1位为0,第i位为1的最小代价。
若第i位本身是1,则dp[i][1]=dp[i-1][0],dp[i][0]=dp[i-1][1]+1+2^(i-1)-1=dp[i-1][1]+2^(i-1);
若第i位本身是0,则dp[i][0]=dp[i-1][0],dp[i][1]=dp[i-1][1]+1+2^(i-1)-1=dp[i-1][1]+2^(i-1);
因为序列长度<=1000,所以要用高精。
View Code
1 import java.math.*; 2 import java.util.Arrays; 3 import java.util.Scanner; 4 class Main{ 5 static BigInteger dp[][]=new BigInteger[1005][2]; 6 static BigInteger po[]=new BigInteger[1005]; 7 static BigInteger min(BigInteger a,BigInteger b) 8 { 9 if(a.compareTo(b)<0) 10 return a; 11 else 12 return b; 13 } 14 public static void main(String[] args) { 15 Scanner cin = new Scanner(System.in); 16 int n; 17 po[0]=BigInteger.ONE; 18 for(n=1;n<=1001;n++) 19 po[n]=po[n-1].add(po[n-1]); 20 while(cin.hasNext()) 21 { 22 n=cin.nextInt(); 23 dp[0][0]=BigInteger.ZERO; 24 dp[0][1]=BigInteger.ZERO; 25 for(int i=1,t;i<=n;i++) 26 { 27 t=cin.nextInt(); 28 if(t==0) 29 { 30 dp[i][0]=dp[i-1][0]; 31 dp[i][1]=dp[i-1][1].add(po[i-1]); 32 } 33 else 34 { 35 dp[i][1]=dp[i-1][0]; 36 dp[i][0]=dp[i-1][1].add(po[i-1]); 37 } 38 } 39 System.out.println(dp[n][0]); 40 } 41 } 42 }