LA4256 UVa11552 dp状态设计

来源:互联网 发布:js时间戳表示24点整 编辑:程序博客网 时间:2024/04/29 23:38

这两个题的状态表示是相似的:
dp[i][j]都表示第i部分放(j)可以得到的最优解。
状态转移也是相似的:
枚举前一部分和当前部分,根据二者关系转移状态。
LA 4256
题意:

给定一个包含n个点的无向连通图和一个长度为L的序列A,你的任务是修改尽量少的数,使序列中任意两个相邻数或者相同,或者对应图中相邻的两个点。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;const int N=200+9;int g[N][N],d[N][N],s[N];/*d[i][j]表示第i位上的数是j,最少需要修改的数如果第i位上的数修改了,那么d[i][j]=d[i-1][k]+1没有修改:d[i][j]=d[i-1][k]当然前提是第i位和第i-1位上的数相等或者相连*/int main() {    int T,n,m,a,b,L;    //freopen ("f.txt", "r", stdin);    scanf ("%d", &T);    while (T--) {        scanf ("%d%d", &n, &m);        memset (g,0,sizeof (g) );        for (int i=0; i<m; i++) {            scanf ("%d%d",&a,&b);            g[a][b]=g[b][a]=1;        }        scanf ("%d",&L);        for (int i=1; i<=L; i++) scanf ("%d",&s[i]);        for (int i=1; i<=n; i++) d[0][i]=0;        for (int i=1; i<=L; i++) {            for (int j=1; j<=n; j++) {                d[i][j]=INF;                for (int k=1; k<=n; k++)                    if (j==k||g[j][k])                        if (j==s[i]) d[i][j]=min (d[i][j],d[i-1][k]);                        else d[i][j]=min (d[i][j],d[i-1][k]+1);            }        }        int ans=INF;        for (int i=1; i<=n; i++) ans=min (ans,d[L][i]);        printf ("%d\n",ans);    }    return 0;}/*SampleInput27 91 22 32 42 63 44 55 67 47 5SampleOutput*/

UVa 11552
题意:

给一个字符串,把它分为k块,例如字符串“helloworld”分成2块,”hello”, “world”,每一块里面的字母可以任意的排序。最终字符串, 连续的一样的字母算作一个chunk,问总chunks最少是多少?

#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int INF=0x3f3f3f3f;const int N = 1e3 + 9;char s[N];int f[N][N],vis[N];;/*f[L][i]表示第L组的末尾放第i个字符得到的最少块如果第L-1组的最后一位和第L组的第一位是一样的,那么可以合并这两个,总chunks可以减少一个即:f[i][j] = min{  如果i-1组的最后一位和i组的第一位不同:  f[i-1][k]+chunks[i],                 如果i-1组的最后一位和i组的第一位相同:  f[i-1][k]+chunks[i]-1  }*/int main() {    //freopen("f.txt","r",stdin);    int T;    scanf ("%d", &T);    int k;    while (T--) {        scanf ("%d%s",&k ,s );        int n = strlen (s);        memset (f,0x3f,sizeof (f) );        for (int L=0; L<n/k; L++) {            memset (vis,0,sizeof (vis) );            for (int i=L*k; i< (L+1) *k; i++)                vis[s[i]]=1;            int cnt=0;            for (int i='a'; i<='z'; i++) cnt+=vis[i];            if (L==0) {                for (int i=0; i<k; i++) f[0][i]=cnt;                continue;            }            for (int i=0; i<k; i++) {                int rear=L*k+i;                for (int j=0; j<k; j++) {                    int pre= (L-1) *k+j;                    if (vis[s[pre]]&& (cnt==1||s[pre]!=s[rear]) )                        f[L][i]=min (f[L][i],f[L-1][j]+cnt-1);                    else f[L][i]=min (f[L][i],f[L-1][j]+cnt);                }            }        }        int ans=INF;        for (int i=0; i<k; i++)            ans=min (ans,f[n/k-1][i]);        printf ("%d\n",ans);    }    return 0;}/*SampleInput25 helloworld7 thefewestflopsSampleOutput810*/
0 0
原创粉丝点击