号插入到这个数字串中,在各种可能形成的
表达式中,值最小的那个表达式的值是多少?
思路:设定dp[i][j],i表示为加号的个数,j表示到达数组的第几个数的最小值;可得dp[m][j]=dp[m-1][m->j-1]+sum(a[m+1->j]);
考察点:能正确找到状态转移,然后看看是否符合dp的特性
收获:任何时候都不能放弃,我做这道题纠结了我3天;
经验:我要想提高自己的成绩必须放弃功名,把算法当成艺术,
算法是一种艺术;
下面是我的代码,第一个是递推;第二个是递归
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int dp[100][100];
int a[100];
int change1(int b,int e)
{
int i;
int n=0;
for(i=b;i<=e;i++)
{
n*=10;
n+=a[i];
}
return n;
}
int change2(int d)
{
int n=0;
int i;
for(i=1;i<d;i++)
{
n*=10;
n+=a[i];
}
return n;
}
int main()
{
int n;
int m;
int i,j,k;
while(1)
{
scanf("%d",&n);
memset(dp,INF,sizeof(dp));
for(i=1;i<=6;i++)
scanf("%d",&a[i]);
for(j=2;j<=6;j++)
for(i=1;i<=j;i++)
dp[1][j]=min(dp[1][j],change2(i)+change1(i,j));
for(m=2;m<=n;m++)
{
for(j=m+1;j<=6;j++)
{
for(i=m;i<j;i++)
{
dp[m][j]=min(dp[m][j],dp[m-1][i]+change1(i+1,j));
}
}
}
printf("%d\n",dp[n][6]);
}
return 0;
}
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int dp[25][25];
int a[20];
int change1(int b,int e)
{
int i;
int n=0;
for(i=b;i<=e;i++)
{
n*=10;
n+=a[i];
}
return n;
}
int rec(int m,int j)
{
int k;
int i;
int n=0;
int t;
if(m==0)
{
for(i=1;i<=j;i++)
{
n*=10;
n+=a[i];
}
return n;
}
else
{
t=INF;
for(i=m;i<j;i++)
t=min(t,rec(m-1,i)+change1(i+1,j));
return t;
}
}
int main()
{
int n;
int i;
scanf("%d",&n);
for(i=1;i<=9;i++)
scanf("%d",&a[i]);
printf("%d\n",rec(n,9));
return 0;
}