UVaOJ 112道题目-数据结构

1、110201/10038 Jolly Jumpers (快乐的跳跃者)

即相邻数字差的绝对值覆盖1~n-1,注意 单词 seccesive,take on

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
int arr[3005];
bool t[3005];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int i;
        for(i=0;i<n;i++)
        {
            scanf("%d",&arr[i]);
        }
        bool flag=true;
        memset(t,0,sizeof(t));
        for(i=1;i<n;i++)
        {
            int f=abs(arr[i]-arr[i-1]);
            if(f>=1&&f<=n-1)
            {
                t[f]=1;
            }
            else
            {
                flag=false;
                break;
            }
        }
        for(i=1;i<n;i++)
        {
            if(t[i]==0)
            {
                flag=false;
                break;
            }
        }
        if(flag)
            printf("Jolly
");
        else
            printf("Not jolly
");
    }
    return 0;
}
View Code

 2、110202/10315 Poker Hands (扑克牌型)

此题为德州扑克,又名港式5张,相同类型比较时注意当相同张数>=3时,只比较相同张数的牌即可

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
char p1[5][5],p2[5][5];
char poker[20]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
int cnt[2][20];
int tot[20];
int dig[2][10];
int ans1[10][10];
int ans2[10][10];
int GetNum(char a)
{
    int i;
    for(i=0;i<13;i++)
    {
        if(poker[i]==a)return i;
    }
}
bool cmp(int a,int b)
{
    return  a<b;
}
int GetType(char p[][5],int type)
{
    int i;
    bool tf=true,df=true;
    dig[type][0]=GetNum(p[0][0]);
    for(i=1;i<5;i++)
    {
        dig[type][i]=GetNum(p[i][0]);
        if(p[i][1]!=p[i-1][1])
        {
            tf=false;
        }
    }
    sort(dig[type],dig[type]+5,cmp);
    for(i=1;i<5;i++)
    {
        if(dig[type][i]!=dig[type][i-1]+1)
        {
            df=false;
            break;
        }
    }
    if(tf&&df)return 1;
    if(tf)return 4;
    if(df)return 5;
    memset(cnt,0,sizeof(cnt));
    memset(tot,0,sizeof(tot));
    for(i=0;i<5;i++)
    {
        cnt[type][dig[type][i]]++;
    }
    for(i=0;i<13;i++)
    {
        tot[cnt[type][i]]++;
    }
    if(tot[4]==1)return 2;
    if(tot[3]==1&&tot[2]==1)return 3;
    if(tot[3]==1)return 6;
    if(tot[2]==2)return 7;
    if(tot[2]==1)return 8;
    return 9;
}
void fun(int ans[][10],int type)
{
    int i,j;
    for(i=0;i<10;i++)
        for(j=0;j<10;j++)ans[i][j]=-1;
    memset(tot,0,sizeof(tot));
    for(i=0;i<5;i++)
    {
        tot[dig[type][i]]++;
    }
    int cnt=0;
    for(i=12;i>=0;i--)
    {
        if(tot[i]!=0)
        {
            cnt+=tot[i];
            if(ans[tot[i]][0]==-1)
                ans[tot[i]][0]=1;
            else ans[tot[i]][0]++;
            int t=ans[tot[i]][0];
            ans[tot[i]][t]=i;
            if(cnt==5)
                return;
        }
    }
}
int main()
{
    int i=0,j;
    while(scanf("%s",p1[0])!=EOF)
    {
        for(i=1;i<5;i++)scanf("%s",p1[i]);
        for(i=0;i<5;i++)scanf("%s",p2[i]);
        int t1=GetType(p1,0);
        int t2=GetType(p2,1);
        int W=-1;
        if(t1<t2)printf("Black wins.
");
        else if(t1>t2)printf("White wins.
");
        else
        {
            fun(ans1,0);
            fun(ans2,1);
            bool find=false;
            for(i=5;i>=1&&!find;i--)
            {
                if(ans1[i][0]!=-1&&ans2[i][0]!=-1)
                {
                    for(j=1;j<=ans1[i][0];j++)
                    {
                        if(ans1[i][j]>ans2[i][j])
                        {
                            W=0;
                            find=true;
                            break;
                        }
                        else if(ans1[i][j]<ans2[i][j])
                        {
                            W=1;
                            find=true;
                            break;
                        }
                    }
                    if(i>=3)break;
                }
            }
            if(W==0)printf("Black wins.
");
            else if(W==1)printf("White wins.
");
            else printf("Tie.
");
        }
    }
    return 0;
}
/*
3H 3D 3S 9C KD 5C 5H 5S 5C 9H 
7H 3H 4H 5H 6H 2S 3S 4S 5S 6S 
6H 2D 4S 9C KD 6C 3H 4S 9C KH 
*/
View Code

 3、110203/10050 Hartals (罢工)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
int cnt[4000];
int h[105];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(cnt,0,sizeof(cnt));
        int i,j,p,N;
        scanf("%d",&N);
        scanf("%d",&p);
        for(i=0;i<p;i++)
        {
            scanf("%d",&h[i]);
        }
        for(i=0;i<p;i++)
        {
            j=h[i];
            while(j<=N)
            {
                cnt[j]++;
                j+=h[i];
            }
        }
        int tot=0;
        for(j=1;j<=N;j++)
        {
            int t=j%7;
            if(t!=6&&t!=0)
            {
                if(cnt[j]!=0)
                    tot++;
            }
        }
        printf("%d
",tot);
    }
    return 0;
}
View Code

 4、110204/843  Crypt Kicker (解密)

非递归方式,需要考虑很多情况

将单词按长度分类链接,若密文找不到匹配的单词则需要回溯

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
char word[1005][20];
int nxt[1005];
int h[20];
int cur[85];
char lin[85][20];
int ch[85];
char alp[100];
int lett[100][20];
int vis[100];
int _alp[100];
int _vis[100];
void Read(int n)
{
    int i;
    memset(h,-1,sizeof(h));
    memset(nxt,-1,sizeof(nxt));
    char tmp[100];
    for(i=0;i<n;i++)
    {
        gets(word[i]);
        int len=strlen(word[i]);
        nxt[i]=h[len];
        h[len]=i;
    }
}
void fun()
{
    char tmp[100];
    while(gets(tmp)!=NULL)
    {
        int i,j,len=strlen(tmp),k=0,m=0,c,b;
        for(i=0;i<=len;i++)
        {
            if(tmp[i]==' '&&k==0)continue;
            if((tmp[i]==' '||i==len)&&k!=0)
            {
                lin[m][k]='';
                m++;
                k=0;
            }
            else
            {
                lin[m][k++]=tmp[i];
            }
        }
        memset(ch,0,sizeof(ch));
        for(i=0;i<26;i++)alp[i]='*';
        memset(cur,0,sizeof(cur));
        memset(lett,0,sizeof(lett));
        memset(vis,0,sizeof(vis));
        bool tag=false;
        bool end=false;
        for(i=0;i<m&&!end&&i>=0;i++)
        {
            len=strlen(lin[i]);
            bool flag=false;
            for(j=0;j<len;j++)
            {
                if(alp[lin[i][j]-'a']=='*')
                    flag=true;
            }
            if(flag||tag)
            {
                bool find=false;
                k=h[len];
                if(tag&&ch[i]==0)
                {
                    i=i-2;
                    continue;
                }
                if(tag&&ch[i]==1)
                {
                    for(j=1;j<=lett[i][0];j++)
                    {
                        c=lett[i][j];
                        b=alp[c]-'a';
                        alp[c]='*';
                        vis[b]=0;
                    }
                    lett[i][0]=0;
                }
                if(tag)k=nxt[cur[i]];
                if(k==-1&&i==0)
                {
                    end=true;
                    break;
                }
                for(;k!=-1&&!find;k=nxt[k])
                {
                    for(j=0;j<len;j++)
                    {
                        c=lin[i][j]-'a';
                        b=word[k][j]-'a';
                        if(alp[c]!='*'&&alp[c]!=word[k][j])break;
                        if(alp[c]=='*'&&vis[b]==1)break;
                    }
                    if(j==len)
                    {
                        lett[i][0]=0;
                        for(j=0;j<26;j++)_alp[j]=alp[j];
                        for(j=0;j<26;j++)_vis[j]=vis[j];
                        for(j=0;j<len;j++)
                        {
                            c=lin[i][j]-'a';
                            b=word[k][j]-'a';
                            if(_alp[c]=='*')
                            {
                                lett[i][0]++;
                                lett[i][lett[i][0]]=c;
                                if(_vis[b]==1)break;
                            }
                            else
                            {
                                if(_alp[c]!=word[k][j])
                                {
                                    break;
                                }
                            }
                            _alp[c]=word[k][j];
                            _vis[b]=1;
                        }
                        if(j!=len)
                        {
                            continue;
                        }
                        else
                        {
                            for(j=0;j<len;j++)
                            {
                                c=lin[i][j]-'a';
                                alp[c]=word[k][j];
                                c=word[k][j]-'a';
                                vis[c]=1;                                                            
                            }
                        }
                        cur[i]=k;
                        find=true;
                        ch[i]=1;
                        tag=false;
                    }
                }
                if(!find)
                {
                    i=i-2;
                    tag=true;
                }
            }
            else
            {
                bool find=false;
                char str[100];
                for(j=0;j<len;j++)
                {
                    int c=lin[i][j]-'a';
                    str[j]=alp[c];
                }
                str[j]='';
                for(k=h[len];k!=-1&&!find;k=nxt[k])
                {
                    if(strcmp(str,word[k])==0)
                    {
                        find=true;
                        break;
                    }
                }
                if(!find)
                {
                    i=i-2;
                    tag=true;
                }
                else
                {
                    tag=false;
                    cur[i]=k;
                    ch[i]=0;
                }
            }
        }

        len=strlen(tmp);
        for(i=0;i<len;i++)
        {
            if(tmp[i]>='a'&&tmp[i]<='z')
            {
                if(end==true)
                {
                    printf("*");
                    continue;
                }
                c=tmp[i]-'a';
                printf("%c",alp[c]);
            }
            else 
                printf("%c",tmp[i]);
        }
        printf("
");
    }
}
int main()
{
    int n;
    char tmp[100];
    scanf("%d",&n);
    getchar();
    Read(n);
    fun();
    return 0;
}
/*
6
and
dick
jane
puff
spot
yertde
bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn

6
and
dick
jane
puff
spot
yertle
xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd

3
aaad
bbb
cccc
xxxx yyy zzzd 


8
and
acq
dick
duop
jane
puff
spot
yertle
bjvg xsb hxsn xsb qymm xsb    rqat xsb pnetfn

1
abbc
abcd
*/
View Code

  递归

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
char word[1005][100];
int h[100],nxt[1005];
char str[1005];
char txt[100][20];
int vis[100];
char val[100];
int xlen[100];
int calc()
{
    int i,j,len=strlen(str),m=0;
    for(i=0;i<len;i++)
    {
        if(i==0||(str[i-1]==' '&&str[i]!=' '))
        {
            j=0;
            while(i<len&&str[i]!=' ')txt[m][j++]=str[i++];
            txt[m][j]='';
            xlen[m]=j;
            m++;
        }
    }
    return m;
}
void DFS(int s,int m,char alp[],int vis[])
{
    int len=xlen[s],i,j;
    if(s>=m)
    {
        for(i=0;i<26;i++)val[i]=alp[i];
        return;
    }
    char _alp[30];
    int _vis[30];
    for(i=h[len];i!=-1;i=nxt[i])
    {
        for(j=0;j<26;j++)
        {
            _alp[j]=alp[j];
            _vis[j]=vis[j];
        }
        for(j=0;j<len;j++)
        {
            int x=txt[s][j]-'a';
            int y=word[i][j]-'a';
            if(_alp[x]=='*')
            {
                if(_vis[y]==1)break;
                _alp[x]=word[i][j];
                _vis[y]=1;
            }
            else
            {
                if(_alp[x]!=word[i][j])break;
            }
        }
        if(j>=len)
        {
            DFS(s+1,m,_alp,_vis);
        }
    }
}
int main()
{
    int n, i,len;
    char alp[30];
    scanf("%d",&n);
    getchar();
    memset(h,-1,sizeof(h));
    for(i=0;i<n;i++)
    {
        gets(word[i]);
        len=strlen(word[i]);
        nxt[i]=h[len];
        h[len]=i;
    }
    while(gets(str)!=NULL)
    {
        int m=calc();
        for(i=0;i<26;i++)
        {
            alp[i]='*';
            val[i]='*';
            vis[i]=0;
        }
        DFS(0,m,alp,vis);
        len=strlen(str);
        for(i=0;i<len;i++)
        {
            char c=str[i];
            if(c!=' ')
            {
                printf("%c",val[c-'a']);
            }
            else 
                printf(" ");
        }
        printf("
");
    }
}
/*

*/
View Code

 5、(POJ)2469 Stack’em Up (完美洗牌术)

 i in position j means that the shuffle moves the ith card in the deck to position j.比较拗口,移动方向需注意,sa[0]=2,意思是第2个位置的数移动到第0位

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
int sa[105][100];
int card[100],_card[100];
char val[15][10]={"2", "3", "4","5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};
char suit[5][10]={"Clubs", "Diamonds", "Hearts", "Spades"};
int Getdig(char str[])
{
    int i,len=strlen(str);
    int tot=0;
    for(i=0;i<len;i++)
    {
        if(isdigit(str[i]))tot=tot*10+str[i]-'0';
    }
    return tot;
}
int main()
{
    int T,n,j,i;
    char num[100];
    //freopen("E:/a.txt","w",stdout);
    //scanf("%d",&T);
    while(scanf("%d",&n)!=EOF)
    {
        
        int tmp;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=52;j++)
            {
                scanf("%d",&sa[i][j]);
            }
        }
        //getchar();
        for(i=1;i<=52;i++)card[i]=i-1;
        //while(gets(num))
        while(scanf("%d",&tmp)!=EOF)
        {
            //tmp=Getdig(num);
            if(tmp==0)break;
            for(i=1;i<=52;i++)
            {
                int a=sa[tmp][i];
                _card[i]=card[a];
            }
            for(i=1;i<=52;i++)
                card[i]=_card[i];
            for(i=1;i<=52;i++)
            {
                int d=card[i]%13;
                int c=card[i]/13;
                printf("%s of %s
",val[d],suit[c]);
            }
            printf("
");
        }
    }
}
/*

*/
View Code

 6、110206/10044 Erdos Numbers 

此题很纠结,一开始没有读清题意,此题可以简化为图模型,求最短路径

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
const int Max=100005;
char pap[Max];
char name[Max][100];
int cur=1;
int h[Max];
int arc[Max];
int nxt[Max];
int tmp[Max];
int dis[Max];
int q[Max];
int tot=0;
void search(int hp,int cn)
{
    int i,j;
    for(i=h[hp];i!=-1;i=nxt[i])
    {
        if(arc[i]==cn)return;
    } 
    arc[tot]=cn;
    nxt[tot]=h[hp];
    h[hp]=tot;
    tot++;
}
void fun()
{
    int i,j,len=strlen(pap),m=0;
    for(i=0;i<len;i++)
    {
        bool sym=false;
        if(i==0||(pap[i]!=' '&&pap[i-1]==' '))
        {
            j=0;
            while(!sym||(pap[i]!=','&&pap[i]!=':'))
            {
                if(pap[i]==',')sym=true;
                name[cur][j++]=pap[i++];
            }
            name[cur][j]='';
            int d=-1;
            for(j=0;j<cur;j++)
            {
                if(strcmp(name[j],name[cur])==0)
                {
                    d=j;
                    break;
                }
            }
            if(d==-1)
            {
                d=cur;
                cur++;
            }
            tmp[m++]=d;
        }
        if(pap[i]==':')break;
    }
    for(i=0;i<m;i++)
    {
        int hp=tmp[i];
        for(j=0;j<m;j++)
        {
            if(i==j)continue;
            search(hp,tmp[j]);
        }
    }
}
void BFS()
{
    int front=0,rear=1,i;
    dis[0]=0;
    while(front<rear)
    {
        int u=q[front];
        front++;
        for(i=h[u];i!=-1;i=nxt[i])
        {
            int ad=arc[i];
            if(dis[ad]==-1)
            {
                dis[ad]=dis[u]+1;
                q[rear++]=ad;
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    int S=1,P,N,i,j;
    strcpy(name[0],"Erdos, P.");
    while(T--)
    {
        cur=1;
        tot=0;
        q[0]=0;
        memset(h,-1,sizeof(h));
        memset(nxt,-1,sizeof(nxt));
        memset(dis,-1,sizeof(dis));
        scanf("%d%d",&P,&N);
        getchar();
        for(i=0;i<P;i++)
        {
            gets(pap);
            fun();
        }
        BFS();
        printf("Scenario %d
",S++);
        for(i=0;i<N;i++)
        {
            gets(pap);
            printf("%s ",pap);
            for(j=0;j<cur;j++)
            {
                if(strcmp(name[j],pap)==0)
                {                    
                    if(dis[j]!=-1)printf("%d
",dis[j]);
                    else printf("infinity
");
                    break;
                }
            }
            if(j>=cur)printf("infinity
");
        }
    }
    return 0;
}
/*
10
8  5
Smith, M.N., Martin, G., Erdos, P.: Newtonian forms of prime factor matrices 
Erdos, P., Zeisig, W.: Stuttering in petri nets
Smith, M.N., Chen, X.: First oder derivates in structured programming
Jablonski, T., Hsueh, Z.: Selfstabilizing data structures
Mith, M.N., Xth, M.N.: Selfstabilizing data structures
fdhgfgh, T., Smith, M.N.: Selfstabilizing data structures
Mith, M.N.:Selfstabilizing data structures
Zeisig, W., Hsueh, Z.: Selfstabilizing data structures
Smith, M.N.
Hsueh, Z.
Chen, X.
Mith, M.N.
Xth, M.N.

8  5
Smith, M.N., Martin, G.,: Newtonian forms of prime factor matrices 
Zeisig, W.: Stuttering in petri nets
Smith, M.N., Chen, X.: First oder derivates in structured programming
Jablonski, T., Hsueh, Z.: Selfstabilizing data structures
Mith, M.N., Xth, M.N.: Selfstabilizing data structures
fdhgfgh, T., Smith, M.N.: Selfstabilizing data structures
Mith, M.N.:Selfstabilizing data structures
Zeisig, W., Hsueh, Z.: Selfstabilizing data structures
Smith, M.N.
Hsueh, Z.
Chen, X.
Mith, M.N.
Xth, M.N.
*/
View Code

 7、110207/10258 Contest Scoreboard (比赛计分板)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
int sub[105][15];
int pro[105][15];
int time[105][15];
int vis[105];
int con[105];
using namespace std;
char lin[100];
void calc(char lin[])
{
    int len=strlen(lin),i;
    int c,p,t;
    char sta;
    int tmp[10],m=0;
    for(i=0;i<len;i++)
    {
        tmp[m]=0;
        if(i==0||(lin[i]!=' '&&lin[i-1]==' '))
        {
            while(i<len&&lin[i]!=' ')
            {
                if(isdigit(lin[i]))
                    tmp[m]=tmp[m]*10+lin[i++]-'0';
                else
                    sta=lin[i++];            
            }
            if(isdigit(lin[i-1]))
            {
                if(m==0)
                    c=tmp[m];
                if(m==1)
                    p=tmp[m];
                else
                    t=tmp[m];
                m++;
            }
        }
    }
    vis[c]=1;
    if(sta=='C'&&pro[c][p]==0)
    {
        pro[c][p]=1;
        time[c][p]=t+20*sub[c][p];
        time[c][10]+=time[c][p];
        pro[c][10]++;
    }
    else if(sta=='I'&&pro[c][p]==0)
    {
        sub[c][p]++;
    }
}
bool cmp(int a,int b)
{
    if(vis[a]>vis[b])
        return 1;
    else if(vis[a]==vis[b])
    {
        if(pro[a][10]>pro[b][10])return 1;
        else if(pro[a][10]==pro[b][10])
        {
            if(time[a][10]<time[b][10])return 1;
            else if(time[a][10]==time[b][10])
            {
                return a<b;
            }
            return 0;
        }
        return 0;    
    }
    return 0;

}
int main()
{
    int T,i;
    scanf("%d",&T);
    getchar();
    gets(lin);
    while(T--)
    {
        memset(sub,0,sizeof(sub));
        memset(pro,0,sizeof(pro));
        memset(time,0,sizeof(time));
        memset(vis,0,sizeof(vis));
        for(i=1;i<=100;i++)con[i]=i;
        while(gets(lin)!=NULL)
        {
            int len=strlen(lin);
            if(len==0)break;
            calc(lin);
        }
        sort(con+1,con+101,cmp);
        for(i=1;i<=100;i++)
        {
            if(vis[con[i]]!=1)break;
            printf("%d %d %d
",con[i],pro[con[i]][10],time[con[i]][10]);
        }
        if(T)printf("
");
    }
    return 0;
}
/*
3

1 2 10 I
3 1 11 C
1 2 19 R
1 2 21 C
1 1 25 C

2 2 10 I
3 1 11 C
1 2 19 R
1 2 21 C
1 1 25 C
*/
View Code

 8、(hdu)1074  Doing homework

用到了动态规划的思想

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
const int Max=1<<16;
const int INF=1000000000;
typedef __int64 lld ;
int h[20];
int dp[Max];
int day[Max];
lld ord[Max];
int dead[20],cost[20];
int node[Max];
int nxt[Max];
char name[20][100];
int tot;
void GetArr(int s,int cnt,int len,int res)
{
    if(len<cnt)return ;
    if(cnt==0)
    {
        node[tot]=res<<len;
        nxt[tot]=h[s];
        h[s]=tot;
        tot++;
        return;
    }
    GetArr(s,cnt-1,len-1,(res<<1)+1);
    GetArr(s,cnt,len-1,res<<1);
}
void PritC(lld cnt,int t)
{
    if(t<=0)return;
    PritC(cnt/16,--t);
    printf("%s
",name[cnt%16]);
}
int main()
{
    memset(nxt,-1,sizeof(nxt));
    memset(h,-1,sizeof(h));
    int i,j,T,C,k;
    for(i=1;i<=15;i++)
    {
        GetArr(i,i,15,0);
    }
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&C);
        for(i=0;i<(1<<C);i++)dp[i]=-INF;
        memset(day,0,sizeof(day));
        memset(ord,-1,sizeof(ord));
        int mx=1<<C;
        for(i=0;i<C;i++)
        {
            scanf("%s%d%d",name[i],&dead[i],&cost[i]);
            dp[1<<i]=dead[i]>cost[i]?0:dead[i]-cost[i];
            day[1<<i]=cost[i];
            ord[1<<i]=i;
        }
        for(i=1;i<C;i++)
        {
            for(k=h[i];k!=-1;k=nxt[k])
            {
                int t=node[k];
                if(t>=mx)continue;
                for(j=0;j<C;j++)
                {
                    int tmp=1<<j;
                    if((tmp&t)!=0)continue;
                    int cnt=tmp|t;
                    if(dp[cnt]==-INF)day[cnt]=day[t]+cost[j];
                    int del=dead[j]-cost[j]-day[t];
                    if(del>0)del=0;
                    int cur=dp[t]+del;
                    lld rd=ord[t]*16+j;
                    if(dp[cnt]<cur)
                    {
                        dp[cnt]=cur;
                        ord[cnt]=rd;
                    }
                    else if(dp[cnt]==cur&&ord[cnt]>rd)
                    {
                        ord[cnt]=rd;
                    }
                }
            }
        }
        //for(i=1;i<(1<<C);i++)printf("dp[%d]=%d,day[%d]=%d,ord[%d]=%d
",i,dp[i],i,day[i],i,ord[i]);
        //printf("ord=%I64d
",ord[(1<<C)-1]);
        printf("%d
",-dp[(1<<C)-1]);
        PritC(ord[(1<<C)-1],C);
    }
    return 0;
}
/*
100
1
English 1 20
2
Computer 3 3
English 3 3
3
Computer 3 3
English 20 1
Math 3 2
6
A 3 3
B 3 3
C 20 1
D 6 3
E 3 2
F 6 3
12
A 3 3
B 3 3
C 20 1
D 6 3
E 3 2
F 6 3
H 3 3
I 3 3
J 20 1
K 6 3
L 3 2
M 6 3
10
A 3 3
B 3 3
C 20 1
D 6 3
E 3 2
F 6 3
H 3 3
I 3 3
J 20 1
K 6 3
8
A 3 3
B 3 3
C 20 1
D 6 3
E 3 2
F 6 3
H 3 3
I 3 3
*/
View Code

 9、110208/10149 Yahtzee (Yahtzee 游戏)

同上一题,使用了状态压缩动态规划

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
int dice[10];
int sco[20][20];
const int Max=1<<13;
int dp[20][Max][65];
int route[20][Max][65];
int h[20];
int tot=0;
int node[Max],nxt[Max];
void fun(int s,int cnt,int len,int res)
{
    if(cnt>len)return;
    if(cnt==0)
    {
        node[tot]=res<<len;
        nxt[tot]=h[s];
        h[s]=tot;
        tot++;
        return;
    }
    fun(s,cnt-1,len-1,(res<<1)+1);
    fun(s,cnt,len-1,(res<<1));
}
bool cmp(int a,int b)
{
    return a<b;
}
int calc(int cnt)
{
    int i,sum=0;
    for(i=0;i<5;i++)
    {
        if(dice[i]==cnt)sum+=cnt;
    }
    return sum;
}
int sk()
{
    int i,cnt=1,max=1;
    for(i=1;i<=5;i++)
    {
        if(i<5&&dice[i]==dice[i-1])cnt++;
        else
        {
            if(cnt>max)max=cnt;
            cnt=1;
        }
    }
    return max;
}
int sl()
{
    int i,cnt=1,max=1;
    for(i=1;i<=5;i++)
    {
        if(i<5&&dice[i]-dice[i-1]==1)cnt++;
        else
        {
            if(max<cnt)max=cnt;
            cnt=1;
        } 
    }
    return max;
}
int sf()
{
    int i,cnt=1,max=1,min=5;
    for(i=1;i<=5;i++)
    {
        if(i<5&&dice[i]==dice[i-1])cnt++;
        else
        {
            if(cnt>max)max=cnt;
            if(cnt<min)min=cnt;
            cnt=1;
        }
    }
    if(max==3&&min==2)return 1;
    return 0;
}
int gp(int tmp)
{
    int cnt=0;
    while(tmp)
    {
        cnt++;
        tmp=tmp>>1;
    }
    return cnt;
}
void DP()
{
    int i,j,k,tmp,t,c,m,s,sum,end=0; 
    for(i=0;i<13;i++)
    {
        k=0;
        if(i<6)k=sco[1][i];
        dp[1][1<<i][k]=sco[1][i];
    }
    for(i=1;i<13;i++)
    {
        for(j=h[i];j!=-1;j=nxt[j])
        {
            tmp=node[j];
            for(k=0;k<13;k++)
            {
                t=1<<k;
                if((tmp&t)!=0)continue;
                c=tmp|t;
                for(m=0;m<=63;m++)
                {
                    if(dp[i][tmp][m]==0)continue;
                    sum=dp[i][tmp][m]+sco[i+1][k];
                    s=m;
                    if(k<6)s+=sco[i+1][k];
                    if(s>63)s=63;
                    if(dp[i+1][c][s]<sum)
                    {
                        dp[i+1][c][s]=sum;
                        route[i+1][c][s]=tmp*100+m;
                    }
                }
            }
        }
    }
    c=(1<<13)-1;
    m=-1;
    for(i=0;i<63;i++)
    {
        //printf("%d-%d
",i,dp[13][c][i]);
        if(dp[13][c][i]>m)
        {
            m=dp[13][c][i];
            end=i;
        }
    }
    int bon=0;
    if(m<(dp[13][c][63]+35))
    {
        m=dp[13][c][63]+35;
        end=63;
        bon=35;
    }
    int w[20],x=13,res[20];
    while(x>1)
    {
        w[x]=gp((route[x][c][end]/100)^c);
        if(x==2)
        {
            w[x-1]=gp(route[x][c][end]/100);
        }
        int t=c;
        c=route[x][t][end]/100;
        end=route[x][t][end]%100;
        x--;
    }
    for(i=1;i<=13;i++)res[w[i]]=sco[i][w[i]-1];
    for(i=1;i<=13;i++)printf("%d ",res[i]);
    printf("%d %d
",bon,m);
}
int main()
{
    int t=1,i,j,sum;
    memset(sco,0,sizeof(sco));
    memset(h,-1,sizeof(h));
    memset(nxt,-1,sizeof(nxt));
    for(i=1;i<=13;i++)
    {
        fun(i,i,13,0);
    }
    while(scanf("%d",&dice[0])!=EOF)
    {
        sum=dice[0];
        for(i=1;i<5;i++)
        {
            scanf("%d",&dice[i]);
            sum+=dice[i];
        }
        sort(dice,dice+5,cmp);
        for (j=0;j<6;j++)sco[t][j]=calc(j+1);
        sco[t][j]=sum; 
        int cnt=sk();
        if(cnt>=3)sco[t][7]=sum;
        if(cnt>=4)sco[t][8]=sum;
        if(cnt==5)sco[t][9]=50;
        cnt=sl();
        if(cnt>=4)sco[t][10]=25;
        if(cnt==5)sco[t][11]=35;
        if(sf())sco[t][12]=40;
        t++;
        if(t>13)
        {    
            memset(dp,0,sizeof(dp));
            memset(route,0,sizeof(route));
            DP();
            memset(sco,0,sizeof(sco));
            t=1;
        }
    }
    return 0;
}
View Code

 10、(poj)1321棋盘问题

同使用状态压缩

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<ctype.h>
using namespace std;
char bord[10][10];
int dp[1<<10];
int tdp[1<<10];
int xdp[1<<10];
int calc(int x,int k)
{
    int cnt=0;
    while(x)
    {
        cnt+=x&1;
        x>>=1;
    }
    return cnt==k;
}

int main()
{
    int n,k,i,j,t;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(n==-1&&k==-1)break;
        getchar();
        int max=1<<n;
        memset(dp,0,sizeof(dp));
        memset(xdp,0,sizeof(xdp));
        for(i=1;i<=n;i++)
        {
            gets(bord[i]);
        }
        for(i=1;i<=n;i++)
        {
            for(j=0;j<n;j++)
            {
                if(bord[i][j]=='#')
                {
                    for(t=0;t<max;t++)tdp[t]=xdp[t];
                    for(t=0;t<max;t++)
                    {
                        int tmp=1<<j;
                        if(t==0)
                        {
                            tdp[tmp]++;
                            continue;
                        }
                        if((t&tmp)!=0)continue;
                        tdp[t|tmp]+=tdp[t];
                    }
                    for(t=0;t<max;t++)dp[t]+=tdp[t]-xdp[t];
                }
            }
            for(j=0;j<max;j++)xdp[j]=dp[j];
        }
        int cnt=0;
        for(i=0;i<max;i++)
        {
            if(calc(i,k))
            {
                cnt+=dp[i];
            }
        }
        printf("%d
",cnt);
    }
    return 0;
}
/*
4 4
#..#
..#.
.#..
#..#

4 4
#..#
#.#.
.#..
#..#
*/
View Code
原文地址:https://www.cnblogs.com/varcom/p/4050206.html