DP专辑

  今天练了一波DP。时间紧迫我就只贴代码了。

20141120

 

fzu2129

http://acm.fzu.edu.cn/problem.php?pid=2129

不同的子序列个数

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define mz(array) memset(array, 0, sizeof(array))
14 #define mf1(array) memset(array, -1, sizeof(array))
15 #define minf(array) memset(array, 0x3f, sizeof(array))
16 #define REP(i,n) for(i=0;i<(n);i++)
17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
18 #define RD(x) scanf("%d",&x)
19 #define RD2(x,y) scanf("%d%d",&x,&y)
20 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
21 #define WN(x) printf("%d\n",x);
22 #define RE  freopen("brackets.in","r",stdin)
23 #define WE  freopen("brackets.out","w",stdout)
24 #define mp make_pair
25 #define pb push_back
26 #define pf push_front
27 #define ppf pop_front
28 #define ppb pop_back
29 typedef long long ll;
30 typedef unsigned long long ull;
31 
32 const double pi=acos(-1.0);
33 const double eps=1e-10;
34 
35 const ll MOD=1e9+7;
36 ll MMOD = MOD*1000000;
37 const int maxn=1111111;
38 
39 int a[maxn];
40 int n;
41 
42 ll f[maxn];
43 int d[maxn];
44 
45 ll farm() {
46     int i;
47     mf1(d);
48     mz(f);
49     f[0]=0;
50     FOR(i,1,n) {
51         if(d[a[i]]==-1) f[i]=(f[i-1] + f[i-1]+1)%MOD;
52         else{
53             f[i]=f[i-1] + f[i-1] - f[d[a[i]]-1];
54             f[i]+=MMOD;
55             f[i]%=MOD;
56         }
57         d[a[i]]=i;
58     }
59     return f[n];
60 }
61 
62 int main() {
63     //RE;
64     //WE;
65     int i;
66     while(RD(n)!=EOF) {
67         FOR(i,1,n)RD(a[i]);
68         printf("%I64d\n",farm());
69     }
70 }
View Code

 

ASC17 A题

Brackets Subsequences

http://codeforces.com/gym/100221

不同的括号子序列个数,要用java的BigInteger。

 1 import java.util.*;
 2 import java.io.*;
 3 import java.math.BigInteger;
 4 
 5 public class Main {
 6     public static final int MAXN = 333;
 7     public static char[] s = null;
 8     public static int N;
 9     public static BigInteger[][] f = new BigInteger[MAXN][MAXN];
10     public static final BigInteger F1 = BigInteger.valueOf(-1);
11     public static final BigInteger ZERO = BigInteger.valueOf(0);
12     public static final BigInteger ONE = BigInteger.valueOf(1);
13 
14     public static BigInteger gank(int last, int o) {
15         // System.out.printf("Gank %d,%d\n",last,o);
16         if (last >= 0 && !f[last][o].equals(F1))
17             return f[last][o];
18         BigInteger re = ZERO;
19         if (o == 0)
20             re = ONE;
21         int i = last + 1;
22         while (i < N && (s[i] != '('))
23             i++;
24         if (i < N)
25             re = re.add(gank(i, o + 1));
26         if (o > 0) {
27             i = last + 1;
28             while (i < N && (s[i] != ')'))
29                 i++;
30             if (i < N)
31                 re = re.add(gank(i, o - 1));
32         }
33         if (last >= 0)
34             f[last][o] = re;
35         return re;
36     }
37 
38     public static void main(String[] args) throws Exception {
39         File fin = new File("brackets.in");
40         File fout = new File("brackets.out");
41         InputStream ins = new FileInputStream(fin);
42         OutputStream ous = new FileOutputStream(fout);
43         Reader.init(ins);
44         String S = Reader.next();
45         s = S.toCharArray();
46         N = S.length();
47         for (int i = 0; i < MAXN; i++) {
48             for (int j = 0; j < MAXN; j++) {
49                 f[i][j] = F1;
50             }
51         }
52         BigInteger ans = gank(-1, 0);
53         ous.write(ans.toString().getBytes());
54     }
55 }
56 
57 class Reader {
58     static BufferedReader reader;
59     static StringTokenizer tokenizer;
60 
61     /** call this method to initialize reader for InputStream */
62     static void init(InputStream input) {
63         reader = new BufferedReader(new InputStreamReader(input));
64         tokenizer = new StringTokenizer("");
65     }
66 
67     /** get next word */
68     static String next() throws IOException {
69         while (!tokenizer.hasMoreTokens()) {
70             // TODO add check for eof if necessary
71             tokenizer = new StringTokenizer(reader.readLine());
72         }
73         return tokenizer.nextToken();
74     }
75 
76     static int nextInt() throws IOException {
77         return Integer.parseInt(next());
78     }
79 
80     static double nextDouble() throws IOException {
81         return Double.parseDouble(next());
82     }
83 }
View Code

 

Knapsack

带路径输出的背包,感觉直接用二维数组会好一点,这个有点乱。

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<map>
  8 #include<set>
  9 #include<stack>
 10 #include<queue>
 11 #include<cassert>
 12 using namespace std;
 13 #define mz(array) memset(array, 0, sizeof(array))
 14 #define mf1(array) memset(array, -1, sizeof(array))
 15 #define minf(array) memset(array, 0x3f, sizeof(array))
 16 #define REP(i,n) for(i=0;i<(n);i++)
 17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 18 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
 19 #define RD(x) scanf("%d",&x)
 20 #define RD2(x,y) scanf("%d%d",&x,&y)
 21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 22 #define WN(x) printf("%d\n",x);
 23 #define RE  freopen("knapsack.in","r",stdin)
 24 #define WE  freopen("knapsack.out","w",stdout)
 25 #define mp make_pair
 26 #define pb push_back
 27 #define pf push_front
 28 #define ppf pop_front
 29 #define ppb pop_back
 30 typedef long long ll;
 31 typedef unsigned long long ull;
 32 typedef long double LD;
 33  
 34 const int maxm=20011;
 35 const int maxn=2011;
 36  
 37 int dp[maxm], c[maxm], n, m, w[maxn], v[maxn];
 38 int d[maxn][maxm];
 39 vector<int> V;
 40 int main() {
 41     RE;
 42     WE;
 43 //    freopen("in.txt","r",stdin);
 44     while(~scanf("%d%d", &n, &m)) {
 45         memset(dp, 0 ,sizeof(dp));
 46         memset(c, -1, sizeof(c));
 47         mz(d);
 48         assert(n>0&&n<=1000);
 49         assert(m>0&&m<=10000);
 50         for(int i=1; i<=n; i++) scanf("%d", &v[i]);
 51         for(int i=1; i<=n; i++) scanf("%d", &w[i]);
 52         for(int i=1;i<=n;i++){
 53                 assert(v[i]>=0&&v[i]<=100);
 54                 assert(w[i]>=0&&w[i]<=100);
 55                 //while(1);
 56                 //return 0;
 57  
 58         }
 59         for(int i=1; i<=n; i++) {
 60             for(int j=m; j>=v[i]; j--) {
 61                 assert(j>=v[i]);
 62                 if(dp[j] < dp[j - v[i]] + w[i]) {
 63                     dp[j] = dp[j - v[i]] + w[i];
 64                     c[j] = i;
 65                     d[i][j]=c[j-v[i]];
 66                 }
 67             }
 68         }
 69         int tmp=0, mx = 0;
 70         for(int i=m; i>0; i--)
 71             if(dp[i] > mx) {
 72                 mx = dp[i];
 73                 tmp = i;
 74             }
 75         V.clear();
 76         if(tmp==0){
 77             puts("0");
 78             continue;
 79         }
 80         V.pb(c[tmp]);
 81         int i=d[c[tmp]][tmp];
 82  
 83         tmp-=v[c[tmp]];
 84         while(i > 0 && tmp>=0) {
 85             V.pb(i);
 86             int t=v[i];
 87             assert(tmp>=0&&tmp<=m);
 88             i=d[i][tmp];
 89             tmp -= t;
 90         }
 91         int sz = V.size();
 92         printf("%d\n",sz);
 93         sort(V.begin(),V.end());
 94         for(int i=0;i<sz;i++){
 95             printf("%d%c",V[i],i==sz-1?'\n':' ');
 96         }
 97         //if(sz==0)puts("");
 98     }
 99     return 0;
100 }
View Code

 

Dominoes

15*100的1*2铺砖

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 #include<climits>
13 using namespace std;
14 #define mz(array) memset(array, 0, sizeof(array))
15 #define mf1(array) memset(array, -1, sizeof(array))
16 #define minf(array) memset(array, 0x3f, sizeof(array))
17 #define REP(i,n) for(i=0;i<(n);i++)
18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
19 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define WN(x) printf("%d\n",x);
24 #define RE  freopen("dominoes.in","r",stdin)
25 #define WE  freopen("dominoes.out","w",stdout)
26 #define mp make_pair
27 #define pb push_back
28 #define pf push_front
29 #define ppf pop_front
30 #define ppb pop_back
31 typedef long long ll;
32 typedef unsigned long long ull;
33 typedef long double LD;
34 const ll MOD=1e9;
35 int m,n;
36  
37 const int maxs=(1<<15)+10;
38 const int maxn=111;
39 int f[maxn][maxs];
40  
41 inline void dfs(const int &H, const int &s,const int &ss,const int &d){
42     if(d==m){
43         f[H][ss] += f[H-1][s];
44         f[H][ss] %= MOD;
45         return;
46     }
47     if(s&(1<<d))dfs(H,s,ss,d+1);
48     else{
49         dfs(H,s, ss|(1<<d) ,d+1);
50         if(d<m-1 && ((s&(1<<(d+1)))==0))
51             dfs(H, s, ss, d+2);
52     }
53 }
54  
55 inline int farm(){
56     int i,j,k;
57     int maxi=1<<m;
58     mz(f);
59     f[0][0]=1;
60     FOR(i,1,n){
61         REP(j,maxi)
62             if(f[i-1][j]){
63                 dfs(i,j,0,0);
64             }
65     }
66     return f[n][0];
67 }
68  
69 int main(){
70     RE;
71     WE;
72     while(RD2(m,n)!=EOF){
73         printf("%d\n",farm());
74     }
75     return 0;
76 }
View Code

 

Number of paths in acyclic graph

有向无环图判1~n的路径数。

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define mz(array) memset(array, 0, sizeof(array))
14 #define mf1(array) memset(array, -1, sizeof(array))
15 #define minf(array) memset(array, 0x3f, sizeof(array))
16 #define REP(i,n) for(i=0;i<(n);i++)
17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
18 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
19 #define RD(x) scanf("%d",&x)
20 #define RD2(x,y) scanf("%d%d",&x,&y)
21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
22 #define WN(x) printf("%d\n",x);
23 #define RE  freopen("countpaths.in","r",stdin)
24 #define WE  freopen("countpaths.out","w",stdout)
25 #define mp make_pair
26 #define pb push_back
27 #define pf push_front
28 #define ppf pop_front
29 #define maxn 100005
30 #define maxm 200005
31 
32 int head[maxn];
33 int en;
34 #define ll long long
35 struct pp{
36     int v,next;
37 
38 }e[maxm];
39 void  add(int u,int v){
40     e[en].v=v;
41     e[en].next=head[u];
42     head[u]=en++;
43 }
44 
45 ll f[maxn];
46 #define mod 1000000007
47 
48 ll dfs(ll x){
49     if(f[x]!=-1)return f[x];
50     ll re=0;
51     int i;
52     for(i=head[x]; i!=-1; i=e[i].next){
53         re+=dfs(e[i].v);
54         re%=mod;
55     }
56     f[x]=re;
57     return re;
58 }
59 
60 int main(){
61     int n,m;
62     RE;
63     WE;
64     scanf("%d%d",&n,&m);
65     memset(head,-1,sizeof(head));
66     en=0;
67     for(int i=0;i<m;i++){
68         int a,b;
69         scanf("%d%d",&a,&b);
70         add(a,b);
71     }
72     memset(f,-1,sizeof(f));
73     f[n]=1;
74     cout<<dfs(1)<<endl;
75 }
View Code

 

Longest common subsequence

LCS带路径输出

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define mz(array) memset(array, 0, sizeof(array))
14 #define mf1(array) memset(array, -1, sizeof(array))
15 #define minf(array) memset(array, 0x3f, sizeof(array))
16 #define REP(i,n) for(i=0;i<(n);i++)
17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
18 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
19 #define RD(x) scanf("%d",&x)
20 #define RD2(x,y) scanf("%d%d",&x,&y)
21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
22 #define WN(x) printf("%d\n",x);
23 #define RE  freopen("lcs.in","r",stdin)
24 #define WE  freopen("lcs.out","w",stdout)
25 #define mp make_pair
26 #define pb push_back
27 #define pf push_front
28 #define ppf pop_front
29 #define ppb pop_back
30 typedef long long ll;
31 typedef unsigned long long ull;
32 typedef long double LD;
33 
34 const int maxn=2111;
35 
36 int n,m;
37 int a[maxn];
38 int b[maxn];
39 
40 int f[maxn][maxn];
41 pair<int,int> pre[maxn][maxn];
42 
43 int ans;
44 vector<int>an;
45 
46 void farm() {
47     int i,j;
48     mz(f);
49     FOR(i,1,n) {
50         FOR(j,1,m) {
51             if(a[i]==b[j]) {
52                 f[i][j]=f[i-1][j-1] + 1;
53                 pre[i][j]=mp(i-1,j-1);
54             } else {
55                 if(f[i-1][j]>f[i][j-1])f[i][j]=f[i-1][j] , pre[i][j]=mp(i-1,j);
56                 else f[i][j]=f[i][j-1] , pre[i][j]=mp(i,j-1);
57             }
58         }
59     }
60     ans=f[n][m];
61     i=n,j=m;
62     an.clear();
63     while(f[i][j]!=0){
64         int qi=pre[i][j].first;
65         int qj=pre[i][j].second;
66         if(f[i][j]>f[qi][qj])an.pb(a[i]);
67         i=qi,j=qj;
68     }
69 }
70 
71 int main() {
72     RE;
73     WE;
74     int i;
75     while(RD(n)!=EOF) {
76         FOR(i,1,n)RD(a[i]);
77         RD(m);
78         FOR(i,1,m)RD(b[i]);
79         farm();
80         printf("%d\n",ans);
81         if(ans>0)printf("%d",an[ans-1]);
82         FORD(i,ans-2,0){
83             printf(" %d",an[i]);
84         }
85         puts("");
86     }
87     return 0;
88 }
View Code

 

Levenshtein distance

编辑距离?队友写的,日后我再看看。

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define mz(array) memset(array, 0, sizeof(array))
14 #define mf1(array) memset(array, -1, sizeof(array))
15 #define minf(array) memset(array, 0x3f, sizeof(array))
16 #define REP(i,n) for(i=0;i<(n);i++)
17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
18 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
19 #define RD(x) scanf("%d",&x)
20 #define RD2(x,y) scanf("%d%d",&x,&y)
21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
22 #define WN(x) printf("%d\n",x);
23 #define RE  freopen("levenshtein.in","r",stdin)
24 #define WE  freopen("levenshtein.out","w",stdout)
25 #define mp make_pair
26 #define pb push_back
27 #define pf push_front
28 #define ppf pop_front
29 #define ppb pop_back
30 
31 //#define inf 0x7fffffff
32 //char a[5005],b[5005];
33 //int dp[5005][5005];
34 //int main(){
35 //    while(scanf("%s%s",a,b)==2){
36 //        int len1=strlen(a);
37 //        int len2=strlen(b);
38 //        for(int i=0;i<=len1;i++)
39 //            for(int j=0;j<=len2;j++)dp[i][j]=inf;
40 //        for(int i=0;i<=len1;i++)dp[0][i]=i;
41 //        for(int i=0;i<=len2;i++)dp[i][0]=i;
42 //        for(int i=1;i<=len1;i++){
43 //            for(int j=1;j<=len2;j++){
44 //                dp[i][j]=min(dp[i-1][j]+1,min(dp[i][j-1]+1,dp[i-1][j-1]+(b[i]==a[j])?0:1));
45 //            }
46 //        }
47 //        cout<<dp[len1][len2]<<endl;
48 //    }
49 //    return 0;
50 //}
51 //
52 
53 char s1[6000],s2[6000];
54 int d[6000][6000];
55 int min(int a,int b,int c) {
56     int t = a < b ? a : b;
57     return t < c ? t : c;
58 }
59 void editDistance(int len1,int len2)
60 {
61     int i,j;
62     for(i = 0;i <= len1;i++)
63         d[i][0] = i;
64     for(j = 0;j <= len2;j++)
65         d[0][j] = j;
66     for(i = 1;i <= len1;i++)
67         for(j = 1;j <= len2;j++)
68         {
69             int cost = s1[i-1] == s2[j-1] ? 0 : 1;
70             int deletion = d[i-1][j] + 1;
71             int insertion = d[i][j-1] + 1;
72             int substitution = d[i-1][j-1] + cost;
73             d[i][j] = min(deletion,insertion,substitution);
74         }
75         printf("%d\n",d[len1][len2]);
76 }
77 int main()
78 {
79     RE;
80     WE;
81     while(scanf("%s %s",s1,s2) != EOF)
82         editDistance(strlen(s1),strlen(s2));
83         return 0;
84 }
View Code

 

Longest increasing subsequence

LIS,带路径输出

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define mz(array) memset(array, 0, sizeof(array))
14 #define mf1(array) memset(array, -1, sizeof(array))
15 #define minf(array) memset(array, 0x3f, sizeof(array))
16 #define REP(i,n) for(i=0;i<(n);i++)
17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
18 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
19 #define RD(x) scanf("%d",&x)
20 #define RD2(x,y) scanf("%d%d",&x,&y)
21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
22 #define WN(x) printf("%d\n",x);
23 #define RE  freopen("lis.in","r",stdin)
24 #define WE  freopen("lis.out","w",stdout)
25 #define mp make_pair
26 #define pb push_back
27 #define pf push_front
28 #define ppf pop_front
29 #define ppb pop_back
30 typedef long long ll;
31 typedef unsigned long long ull;
32 typedef long double LD;
33 
34 const int maxn=5555;
35 
36 int n;
37 int a[maxn];
38 
39 int f[maxn];
40 int pre[maxn];
41 
42 int ans;
43 vector<int>an;
44 
45 inline void farm() {
46     int i,j;
47     mz(pre);
48     FOR(i,1,n) {
49         f[i]=1;
50         FOR(j,1,i-1) {
51             if(a[i]>a[j] && f[j]+1>f[i]) {
52                 f[i]=f[j]+1;
53                 pre[i]=j;
54             }
55         }
56     }
57     ans=0;
58     int ai=0;
59     FOR(i,1,n) {
60         if(f[i]>ans)ans=f[i], ai=i;
61     }
62     i=ai;
63     an.clear();
64     REP(j,ans) {
65         an.pb(a[i]);
66         i=pre[i];
67     }
68 }
69 
70 int main() {
71     RE;
72     WE;
73     int i;
74     while(RD(n)!=EOF) {
75         if(n>=maxn)while(1);
76         FOR(i,1,n)RD(a[i]);
77         farm();
78         printf("%d\n",ans);
79         if(ans>0)printf("%d",an[ans-1]);
80         FORD(i,ans-2,0) {
81             printf(" %d",an[i]);
82         }
83         puts("");
84     }
85     return 0;
86 }
View Code

 

 Maximal weight matching in tree

树上选一些边,没有公共顶点,要求边权和最大。

树DP,队友写的。

哇,代码不见啦!反正就是f[i][j],j=0~1,0是不用这个点,1是用这个点。

 

Matrix multiplication

矩阵链乘,加括号使得代价最小,带路径输出。算法导论题,队友写的,碉

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 #include<climits>
13 using namespace std;
14 #define mz(array) memset(array, 0, sizeof(array))
15 #define mf1(array) memset(array, -1, sizeof(array))
16 #define minf(array) memset(array, 0x3f, sizeof(array))
17 #define REP(i,n) for(i=0;i<(n);i++)
18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
19 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define WN(x) printf("%d\n",x);
24 #define RE  freopen("matrix.in","r",stdin)
25 #define WE  freopen("matrix.out","w",stdout)
26 #define mp make_pair
27 #define pb push_back
28 #define pf push_front
29 #define ppf pop_front
30 #define ppb pop_back
31 typedef long long ll;
32 typedef unsigned long long ull;
33 typedef long double LD;
34 
35 const int maxn=1000 + 10;
36 
37 int n, a[maxn], b[maxn], m[maxn][maxn], s[maxn][maxn];
38 void Print(int l ,int r){
39     if(l == r){
40         putchar('A');
41         return;
42     }
43     putchar('(');
44     Print(l, s[l][r]);
45     Print(s[l][r] + 1, r);
46     putchar(')');
47 }
48 int main(){
49     RE;
50     WE;
51     scanf("%d", &n);
52     for(int i=1; i<=n; i++) scanf("%d%d", &a[i], &b[i]), m[i][i] = 0;
53     for(int l=2; l<=n; l++){
54         for(int i=1; i<=n-l+1; i++){
55             int j = i + l -1;
56             m[i][j] = INT_MAX;
57             for(int k=i; k<j; k++){
58                 int q = m[i][k] + m[k + 1][j] + a[i] * b[k] * b[j];
59                 if(q < m[i][j]){
60                     m[i][j] = q;
61                     s[i][j] = k;
62                 }
63             }
64         }
65     }
66 //    cout << m[1][n] << endl;
67     Print(1, n);
68     return 0;
69 }
View Code

 

Longest subpalindrome

最长回文子串,带路径输出。

f[l][r]记录区间[l,r]的最长回文子串长度,区间从小到大搞。

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 #include<climits>
 13 using namespace std;
 14 #define mz(array) memset(array, 0, sizeof(array))
 15 #define mf1(array) memset(array, -1, sizeof(array))
 16 #define minf(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define WN(x) printf("%d\n",x);
 24 #define RE  freopen("palindrome.in","r",stdin)
 25 #define WE  freopen("palindrome.out","w",stdout)
 26 #define mp make_pair
 27 #define pb push_back
 28 #define pf push_front
 29 #define ppf pop_front
 30 #define ppb pop_back
 31 typedef long long ll;
 32 typedef unsigned long long ull;
 33 typedef long double LD;
 34 
 35 const int maxn=2222;
 36 
 37 char s[2222];
 38 int f[2222][2222];
 39 pair<int,int> pre[maxn][maxn];
 40 
 41 int ans;
 42 vector<char>anl,anr;
 43 
 44 void farm(){
 45     int len=strlen(s);
 46     int i,j,k;
 47     mz(f);
 48     mf1(pre);
 49     REP(i,len)f[i][i]=1 , pre[i][i]=mp(-1,-1);
 50     FOR(k,1,len-1){
 51         FOR(i,0,len-2){
 52             j=i+k;
 53             if(j>len-1)break;
 54             if(s[i]==s[j]){
 55                 if(j-i>1){
 56                     f[i][j]=f[i+1][j-1]+2;
 57                     pre[i][j] = mp(i+1,j-1);
 58                 }else{
 59                     f[i][j]=2;
 60                     pre[i][j]=mp(-1,-1);
 61                 }
 62             }else{
 63                 if(f[i][j-1] > f[i+1][j])f[i][j]=f[i][j-1] , pre[i][j]=mp(i,j-1);
 64                 else f[i][j]=f[i+1][j] , pre[i][j]=mp(i+1,j);
 65             }
 66         }
 67     }
 68     ans=f[0][len-1];
 69     i=0;
 70     j=len-1;
 71     anl.clear();
 72     anr.clear();
 73     int qi,qj;
 74     while(i>=0 && j>=0){
 75         qi=pre[i][j].first;
 76         qj=pre[i][j].second;
 77         if(qi<0 || qj<0){
 78             if(f[i][j]!=0){
 79                 if(i==j)anl.pb(s[i]);
 80                 else anl.pb(s[i]),anr.pb(s[i]);
 81             }
 82             break;
 83         }
 84         //printf("%d,%d %d,%d %d,%d\n",i,j,qi,qj,f[i][j] , f[qi][qj]);
 85         if(f[i][j] > f[qi][qj]){
 86             if(i!=j)anl.pb(s[i]), anr.pb(s[i]);
 87             else anl.pb(s[i]);
 88             //printf("%d,%c\n",i!=j,s[i]);
 89         }
 90         i=qi;
 91         j=qj;
 92     }
 93 }
 94 
 95 int main(){
 96     int i;
 97     RE;
 98     WE;
 99     while(scanf("%s",s)!=EOF){
100         farm();
101         printf("%d\n",ans);
102         REP(i,anl.size())putchar(anl[i]);
103         FORD(i,anr.size()-1,0)putchar(anr[i]);
104         puts("");
105     }
106 }
View Code

 

Travelling salesman problem

旅行商问题,代码不见了。

f[i][j],一个是状压的到过哪个地方的状态,另一个是最后在哪个点。

 

String Decomposition

把字符串弄成又几个子串增殖出来的

太难啦,还没做出来

 

Solid Tilings

另一种比较难的铺砖,还没看。

posted @ 2014-11-20 21:00  带鱼Yuiffy  阅读(296)  评论(0编辑  收藏  举报