4576 | njczy2010 | C | Accepted | 860 KB | 140 ms | G++ | 2063 B | 2014-10-16 09:51:19 |
哎,为啥1000*100*100的复杂度的dp就不敢敲了呢,,,真是2
涉及到可能有后效性的时候,一维就不行了,要扩维。本题,一个状态的变化会影响后两个,所以要用三维。
lockerTime Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1418 Accepted Submission(s): 620
题目:给出两个串,每次可以选择连续的1-3个数字,进行同时加1或者同时减1,问最少经过多少次操作,将一个串转变为另外一个串
http://acm.hdu.edu.cn/showproblem.php?pid=4433
以前有类似的题目,BFS就可以了
不过这题的数据量太大,听说也有不少是搜索过的
我写了一个矬B的搜索,反正是挂了,没加什么优化
训练的时候,yobobobo的DP解法比较接近,可是最终貌似卡在后效性上?
dp[i][j][k]表示 前i个已经完全匹配,而这时候,第i+1个已经加了j位,第i+2位已经加了k
转移分为两步,枚举加,枚举减
注意如果第i位加了a,第i+1位加了b,第i+2位加了c,那么a>=b>=c这个关系不能错
以下题解转自:http://www.cnblogs.com/kuangbin/archive/2012/10/27/2742672.html
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<map> 9 #include<set> 10 #include<string> 11 //#include<pair> 12 13 #define N 1005 14 #define M 1000005 15 #define mod 1000000007 16 #define inf 0x3f3f3f3f 17 //#define p 10000007 18 #define mod2 100000000 19 #define ll long long 20 #define LL long long 21 #define maxi(a,b) (a)>(b)? (a) : (b) 22 #define mini(a,b) (a)<(b)? (a) : (b) 23 24 using namespace std; 25 26 char s1[N]; 27 char s2[N]; 28 int a[N]; 29 int dp[N][12][12]; 30 int n; 31 32 void ini() 33 { 34 n=strlen(s1); 35 memset(dp,inf,sizeof(dp)); 36 int i; 37 a[0]=0; 38 for(i=0;i<n;i++){ 39 a[i+1]=s1[i]-s2[i]; 40 if(a[i+1]<0) a[i+1]+=10; 41 } 42 // for(i=1;i<=n;i++){ 43 // printf("%d",a[i]); 44 // }printf("\n"); 45 a[n+1]=0; 46 a[n+2]=0; 47 } 48 49 50 void solve() 51 { 52 int i,j,k,jj,kk,t1,t2; 53 dp[0][0][0]=0; 54 for(i=1;i<=n;i++){ 55 for(j=0;j<=9;j++){ 56 for(k=0;k<=9;k++){ 57 t1=(a[i]-j+10)%10; 58 for(jj=0;jj<=t1;jj++){ 59 for(kk=0;kk<=jj;kk++){ 60 dp[i][ (jj+k)%10 ][kk]=min(dp[i][ (jj+k)%10 ][kk],dp[i-1][j][k]+t1); 61 } 62 } 63 64 t2=10-t1; 65 for(jj=0;jj<=t2;jj++){ 66 for(kk=0;kk<=jj;kk++){ 67 dp[i][ (k-jj+10)%10 ][(10-kk)%10]=min(dp[i][ (k-jj+10)%10 ][(10-kk)%10],dp[i-1][j][k]+t2); 68 } 69 } 70 } 71 } 72 } 73 74 // for(i=1;i<=n;i++){ 75 // for(j=0;j<=9;j++){ 76 // for(k=0;k<=9;k++) printf(" i=%d j=%d k=%d dp=%d\n",i,j,k,dp[i][j][k]); 77 // } 78 // } 79 return ; 80 } 81 82 void out() 83 { 84 printf("%d\n",dp[n][0][0]); 85 } 86 87 int main() 88 { 89 //freopen("data.in","r",stdin); 90 //freopen("data.out","w",stdout); 91 //scanf("%d",&T); 92 // for(int ccnt=1;ccnt<=T;ccnt++) 93 // while(T--) 94 while(scanf("%s%s",s1,s2)!=EOF) 95 { 96 //if(n==0 && k==0 ) break; 97 //printf("Case %d: ",ccnt); 98 ini(); 99 solve(); 100 out(); 101 } 102 103 return 0; 104 }