POJ Best Sequence
http://poj.org/problem?id=1699
题意:给你n个字符窜,求其所能拼接的最短长度。
分析:预处理下,dp[i][j]表示j接在i后头的最短长度,然后记忆化搜索
这里注意的是 ACTT
CT 这个答案是6 因为T和/0不相等
还有就是刚进入的时候,要把当前的字符窜算进去,应为pos代表的是前一个,若带入是-1的话,会超出数组。
dp[i][j]表示状态i,第j个结尾。
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; const int MN=30; const int INF=999999; char s[MN][MN]; int dp[MN][MN];//j接在i后头最短是多长 int f[1024][MN]; int n; int judge(int len1,int len2,int pos1,int pos2) { int ans=len2,tmp,tt=0; if(len1>len2) tt=len1-len2; for(int i=tt; i<len1; i++) { tmp=len2; if(s[pos1][i]==s[pos2][0]) { int x=i,y=0; while(1) { if(s[pos1][x++]!=s[pos2][y++]) break; if(x==len1) return len2-y; } } } return len2; } void work() { for(int i=0; i<n; i++) { int len1=strlen(s[i]); for(int j=0; j<n; j++) { if(i==j) continue; int len2=strlen(s[j]); int tmp=judge(len1,len2,i,j); dp[i][j]=tmp; } } } int DFS(int ans,int pos) { if(f[ans][pos]!=-1) return f[ans][pos]; if(ans==0) return f[ans][pos]=0; int sum=INF; for(int i=0; i<n; i++) { if(ans&(1<<i)) { ans^=(1<<i); int tmp=DFS(ans,i)+dp[pos][i]; ans^=(1<<i); if(sum>tmp) { sum=tmp; // de[i]=pos; } } } return f[ans][pos]=sum; } void debug1() { for(int i=0; i<n; i++) { printf("%d: ",i); for(int j=0; j<n; j++) if(i!=j) printf("%d ",dp[i][j]); puts(""); } } int main() { int i,j,T; scanf("%d",&T); while(T--) { memset(f,-1,sizeof(f)); scanf("%d",&n); memset(dp,0,sizeof(dp)); for(i=0; i<n; i++) { scanf("%s",s[i]); } work(); // debug1(); int sum=INF; for(i=0; i<n; i++) { int l=strlen(s[i]); int tmp=(1<<n)-1; tmp^=(1<<i); f[(1<<n)-1][i]=l+DFS(tmp,i); } int tt; for(i=0; i<n; i++) { if(sum>f[(1<<n)-1][i]) { sum=f[(1<<n)-1][i]; } } printf("%d ",sum); } return 0; }
POJ 1950 Dessert
http://poj.org/problem?id=1950
题意:n个数1 2 3.......n,加入运算符使其结果为0
分析:dfs搜索,具体看代码,主要是几个数字结合的时候,前一个数要先减去,再加上结合的数。
9.10=9*100+10 而不是9*10+10
还有这里只打印前20个
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define LL long long int cas; const int MN=20; char num[2000][100]; char tmp[MN*MN]; int n; void DFS(int cur,LL sum,int cnt,LL pre,int flag) {//当前第几个数,当前的和,当前字符个数,前一个数十什么,前一个符号是+还是- if(cur==n+1) { if(sum==0) { tmp[cnt]='