题意:给出m个长度为3的由0~9组成的字符串,每个字符串有一个权值,可正可负。要求构造出一个长度为n的字符串,若字符串中包含题目给出的某个字符串,则获得该字符串的权值。求一个权值最大的字符串。
分析:其实很早就想到了记录当前位和上一位的数字的dp方程,但是由于没理解题目意思(貌似题目说的也不太清楚),所以不确定如果包含同一个字符串多次,该字符串的权值是只算一次还是算多次。在网上看了看他人的解答,原来是按算多次来理解的。于是下手写,细想的时候发现顺推不能保证字典序最小,于是加了个string记录,还是顺推,果断超时了。才想到从右往左倒着dp,就能保证最后得出的字符串是字典序最小的了,这一点想一想dp时循环的顺序就很容易理解了。
用f[now][i][j]表示从右往左到第now位,且第now位上数字为i,第now-1位上的数字为j的最大值,则f[now][i][j]=max{
f[now-1][j][k]+w[100*i+10*j+k] }
#include <iostream>
#include 
<stdio.h>
#include 
<memory.h>
#include 
<stdlib.h>
#include 
<limits.h>
using namespace std;
#define inf INT_MAX

int f[10010][10][10],pre[10010][10][10],n,m,w[1010],out[10010];

int main()
{
    
int i,j,k,ans,p,q,tem,x,y,now;
    
while(scanf("%d%d",&m,&n)!=EOF)
    
{
        memset(w,
0,sizeof(w));
        
for(i=1;i<=m;i++)
        
{
            scanf(
"%d%d",&x,&y);
            w[x]
=y;
        }

        
for(j=0;j<=9;j++)
        
{
            
for(k=0;k<=9;k++)
            
{
                f[
2][j][k]=0;
            }

        }

        
for(now=3;now<=n;now++)  // dp
        {
            
for(i=0;i<=9;i++)
            
{
                
for(j=0;j<=9;j++)
                
{
                    f[now][i][j]
=-inf;
                    
for(k=0;k<=9;k++)
                    
{
                        
if(f[now-1][j][k]+w[100*i+10*j+k]>f[now][i][j])
                        
{
                            f[now][i][j]
=f[now-1][j][k]+w[100*i+10*j+k];
                            pre[now][i][j]
=k;   
                        }

                    }

                }

            }

        }

        ans
=-inf;
        
for(i=0;i<=9;i++)
        
{
            
for(j=0;j<=9;j++)
            
{
                
if(f[n][i][j]>ans)
                
{
                    ans
=f[n][i][j];
                    p
=i; q=j;
                }

            }

        }

        i
=n;
        
while(i>2)
        
{
            printf(
"%d",p);
            tem
=pre[i][p][q];
            p
=q; q=tem;
            i
--;
        }

        printf(
"%d%d\n",p,q);
    }

    
return 0;
}