【openjudge 2.6基本算法之动态规划】(合集)
1481:Maximum sum
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[50010][2],g[50010][2],sum[50010][2];
int n,T,a[50010];
int main()
{
int i,j;
scanf("%d",&T);
while(T)
{
memset(sum,128,sizeof(sum));
memset(f,128,sizeof(f));
memset(g,128,sizeof(g));
int ans=f[0][0];
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%d",&a[i]);
f[1][0]=f[1][1]=a[1]; sum[1][0]=a[1];
for(i=2;i<=n;++i)
{
int s;
sum[i][0]=sum[i-1][0];
f[i][1]=max(f[i-1][1],f[i-1][0])+a[i];
f[i][0]=a[i];
if(f[i][1]<f[i][0]) s=f[i][0];
else s=f[i][1];
if(s>sum[i][0]) sum[i][0]=s;
}
g[n][0]=g[n][1]=a[n]; sum[n][1]=a[n];
for(i=n-1;i>0;--i)
{
int s;
sum[i][1]=sum[i+1][1];
g[i][1]=max(g[i+1][1],g[i+1][0])+a[i];
g[i][0]=a[i];
if(g[i][1]<g[i][0]) s=g[i][0];
else s=g[i][1];
if(s>sum[i][1]) sum[i][1]=s;
}
for(i=1;i<n;++i)
{
int s=sum[i][0]+sum[i+1][1];
if(s>ans) ans=s;
}
printf("%d\n",ans);
T--;
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[10010],n,a[10010];
int main()
{
int i,j;
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
f[i]=1;
for (i=2;i<=n;i++)
for (j=1;j<i;j++)
if (a[j]<a[i]&&f[j]+1>f[i])
f[i]=f[j]+1;
for (i=2;i<=n;i++)
f[i]=max(f[i-1],f[i]);
printf("%d",f[n]);
return 0;
}
#include<cstdio>
#include<cstring>
using namespace std;
int n,a1,a2;
int main()
{
int i;
scanf("%d",&n);
if (n==1)
{printf("%d",1); return 0;}
if (n==2)
{printf("%d",2); return 0;}
a1=1; a2=2;
for (i=3;i<=n;i++)
{
int t;
t=a1+a2; a1=a2; a2=t;
}
printf("%d",a2);
return 0;
}
#include<cstdio>
#include<cstring>
using namespace std;
int f[30][30],n,m;
int main()
{
int i,j;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (i+j!=2)
f[i][j]+=f[i-1][j]+f[i][j-1];
else f[i][j]=1;
printf("%d",f[n][m]);
return 0;
}
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int a[30],n,m,ans;
bool p[30];
void dfs(int j,int sum)
{
if (sum==m)
{ans++; return; }
if (sum>m) return;
for (int i=j;i<=n;i++)
if (p[i])
{
p[i]=false;
dfs(i,sum+a[i]);
p[i]=true;
}
return;
}
int main()
{
int i;
scanf("%d%d",&n,&m);
memset(p,true,sizeof(p));
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
dfs(1,0);
printf("%d",ans);
return 0;
}
(这题dfs就能切。。。数据弱啊!)#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char a[1010],b[1010];
int f[1010][1010],la,lb,n;
int main()
{
int i,j,k;
scanf("%d",&n);
for (k=1;k<=n;k++)
{
cin>>a>>b;
la=strlen(a); lb=strlen(b);
memset(f,0,sizeof(f));
for (i=1;i<=la;i++)
f[i][0]=i;
for (i=1;i<=lb;i++)
f[0][i]=i;
for (i=1;i<=la;i++)
for (j=1;j<=lb;j++)
if (a[i-1]==b[j-1])
f[i][j]=f[i-1][j-1];
else
f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
printf("%d\n",f[la][lb]);
}
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[110][110],a[110],n,k;
int main()
{
int i,j;
scanf("%d%d",&n,&k);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
{
f[i][a[i]%k]=max(f[i][a[i]%k],a[i]);
for (j=0;j<k;j++)
if (f[i][j]!=0)
{
f[i+1][(j+a[i+1])%k]=max(f[i+1][(j+a[i+1])%k],f[i][j]+a[i+1]);
f[i+1][j]=max(f[i+1][j],f[i][j]);
}
}
printf("%d",f[n][0]);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int f[10010][100],a[10010],n,k;
int main()
{
int i,j;
scanf("%d%d",&n,&k);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
f[1][a[1]%k]=1;
for (i=1;i<=n;i++)
for (j=0;j<k;j++)
if (f[i][j]!=0)
{
f[i+1][(abs(j+a[i+1]))%k]=1;
f[i+1][(abs(j-a[i+1]))%k]=1;
}
if (f[n][0]!=0)
printf("YES");
else printf("NO");
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[10010],a[10010],n;
int main()
{
int i,j;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
f[i]=a[i];
}
for (i=2;i<=n;i++)
for (j=1;j<i;j++)
if (a[j]<a[i]&&f[j]+a[i]>f[i])
f[i]=f[j]+a[i];
for (i=2;i<=n;i++)
f[i]=max(f[i-1],f[i]);
printf("%d",f[n]);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[1010][510],tl[1010],num[1010];
int n,m,k;
int main()
{
int i,j,l;
scanf("%d%d%d",&n,&m,&k);
for (i=1;i<=k;i++)
scanf("%d%d",&num[i],&tl[i]);
for (l=1;l<=k;l++)
for (i=n;i>=num[l];i--)
for (j=m;j>=tl[l];j--)
f[i][j]=max(f[i][j],f[i-num[l]][j-tl[l]]+1);
if (f[n][m]==0)
{printf("0 %d",m); return 0;}
int a1,a2;
a1=a2=0;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (f[i][j]>a1||f[i][j]==a1&&m-j>a2)
{a1=f[i][j]; a2=m-j;}
printf("%d %d",f[n][m],a2);
return 0;
}
#include<cstdio>
#include<cstring>
using namespace std;
int f[25],d=1,x=1,b=1,n;
int main()
{
int i;
scanf("%d",&n);
f[1]=3;
for (i=2;i<=n;i++)
{
int t=0;
f[i]+=d*2+b*3+x*2;
t=d+b+x; d+=b; x+=b; b=t;
}
printf("%d",f[n]);
return 0;
}
【奇怪递推方法开心水过~】#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[1000010],a[110],v[110],t,n,k;
void do1(int m,int b,int j)
{
int x;
x=max(m+k,a[j]-1);
for (int i=m+1;i<=x;i++)
f[i]=b;
return;
}
int main()
{
int i,j,l;
scanf("%d",&t);
for (l=1;l<=t;l++)
{
int x;
memset(f,0,sizeof(f));
memset(a,0,sizeof(a));
scanf("%d%d",&n,&k);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
scanf("%d",&v[i]);
do1(a[1],v[1],2);
f[a[1]]=v[1];
for (i=2;i<=n;i++)
{
for (j=max(a[i]-k,1);j<a[i];j++)
f[a[i]]=max(f[a[i]],f[j]);
f[a[i]]=max(f[max(a[i]-k-1,0)]+v[i],f[a[i]]);
if (i!=n)
do1(a[i],f[a[i]],i+1);
}
printf("%d\n",f[a[n]]);
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[10010],w[5]={0,10,20,50,100},n;
int main()
{
int i,j;
scanf("%d",&n);
if (n==0)
{printf("0"); return 0;}
if ((n%10!=0))
{printf("0"); return 0;}
f[0]=1;
for (i=1;i<=4;i++)
for (j=w[i];j<=n;j++)
f[j]+=f[j-w[i]];
printf("%d",f[n]);
}
#include<cstdio>
#include<cstring>
using namespace std;
int f[15][15],n,m,t;
int main()
{
int i,j,k;
scanf("%d",&t);
for (k=1;k<=t;k++)
{
scanf("%d%d",&n,&m);
f[0][0]=1;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (i>=j)
f[i][j]=f[i-1][j-1]+f[i-j][j];
for (i=1;i<m;i++)
f[n][m]+=f[n][i];
printf("%d\n",f[n][m]);
memset(f,0,sizeof(0));
}
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[110][110],f[110][110],n;
int main()
{
int i,j;
scanf("%d",&n);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
scanf("%d",&a[i][j]);
memset(f,127/3,sizeof(f));
f[1][1]=a[1][1];
f[1][2]=f[1][1]+a[1][2];
f[2][1]=f[1][1]+a[2][1];
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
int sum;
sum=min(f[i][j-1],f[i-1][j])+a[i][j];
f[i][j]=min(f[i][j],sum);
}
printf("%d",f[n][n]);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int dis[610],f[510][510],last[510][510],n,m;
int main()
{
int i,j,k;
scanf("%d%d",&n,&m);
memset(f,127,sizeof(f));
memset(last,0,sizeof(last));
for (i=2;i<=n;i++)
{
int x;
scanf("%d",&x);
dis[i]=dis[i-1]+x;
}
for (i=1;i<=n;i++)
for (j=i;j<=n;j++)
{
int mid;
mid=(i+j)>>1;
for (k=i;k<=j;k++)
last[i][j]+=abs(dis[k]-dis[mid]);
}
for (i=1;i<=n;i++)
f[1][i]=last[1][i];
for (i=2;i<=m;i++)
for (j=i;j<=n;j++)
for (k=i-1;k<j;k++)
f[i][j]=min(f[i][j],f[i-1][k]+last[k+1][j]);
printf("%d",f[m][n]);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[110][20],n,m;//f[i][j]表示i层楼,j个鸡蛋
int main()
{
int i,j,k;
while ((scanf("%d%d",&n,&m)==2)&&n!=0&&m!=0)
{
memset(f,0,sizeof(f));
for (i=1;i<=n;i++)
f[i][1]=i;//如果只有一个鸡蛋,那么它只能从第一层开始扔,最坏情况为i次
for (i=1;i<=n;i++)
for (j=2;j<=m;j++)
{
f[i][j]=max(f[i-1][j-1],f[i+1][j])+1;//从在i层楼扔j个鸡蛋碎了的情况和没碎的情况中选择一个最优的(因为是最坏情况,所以要找最大的),并加上当前扔的这一次作为f[i][j]的初值
for (k=2;k<=i;k++)
f[i][j]=min(f[i][j],max(f[k-1][j-1],f[i-k][j])+1);//从第1层到第i层向下扔中选择最优值(分碎和没碎两种情况)并加上当前这种情况,与f[i][j]的初值相比,选最优的(因为是最坏情况的最优策略,所以要找最小值)
}
printf("%d\n",f[n][m]);
}
return 0;
}
//多组数据!!好吧,我又没仔细看题……
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[100010],t,n,a[100010];
int main()
{
int i,k;
scanf("%d",&t);
for (k=1;k<=t;k++)
{
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
f[1]=a[1]; f[2]=max(a[1],a[2]);
for (i=3;i<=n;i++)
{
f[i]=max(f[i-1],f[i-2]+a[i]);
f[i]=max(f[i-1],f[i]);
}
printf("%d\n",f[n]);
}
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[100010],g[100010],n,a[100010];
int main()
{
int i,j,k;
scanf("%d",&n);
for (k=1;k<=n;k++)
{
int t,m,ans=0;
scanf("%d",&t);
for (i=1;i<=t;i++)
scanf("%d",&a[i]);
m=a[1];
for (i=2;i<=t;i++)
{
f[i]=a[i]-m;
if (a[i]<m) m=a[i];
}
m=a[t];
for (i=t;i>0;i--)
{
g[i]=m-a[i];
if (a[i]>m) m=a[i];
}
for (i=2;i<=t;i++)
f[i]=max(f[i-1],f[i]);
for (i=t;i>1;i--)
g[i]=max(g[i],g[i-1]);
for (i=1;i<t;i++)
ans=max(f[i]+g[i+1],ans);
printf("%d\n",ans);
}
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[20][20],n,m,t;
int main()
{
int i,j,k;
f[0][0]=1;
for (i=1;i<=10;i++)
for (j=1;j<=10;j++)
if (i>=j)
f[i][j]=f[i-1][j-1]+f[i-j][j];
for (i=1;i<=10;i++)
for (j=1;j<=10;j++)
f[i][j]+=f[i][j-1];
scanf("%d",&t);
for (i=1;i<=t;i++)
{
scanf("%d%d",&n,&m);
printf("%d\n",f[n][m]);
}
return 0;
}
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int n,f[1010],l1;//f[i]表示前i-1位切了多少刀
char a[1010];
bool check(int s,int l)//判断能否构成回文
{
while (s<=l)
if (a[s]==a[l])
{s++; l--; }
else return false;
return true;
}
int main()
{
int i,j,k;
scanf("%d",&n);
for (k=1;k<=n;k++)
{
cin>>a;
l1=strlen(a);
for (i=0;i<l1/2;i++)
if (a[i]!=a[l1-1-i])
break;
if (i==l1/2)
{printf("0\n"); continue;}
f[0]=0;
for (i=1;i<l1;i++)
f[i]=i;
for (i=1;i<l1;i++)
{
if (check(0,i))//如果到当前位能构成一个回文,就不用切
{f[i]=0; continue;}
for (j=0;j<i;j++)
if (check(j+1,i))//如果在j处切1刀,从j+1到i能构成回文,就可以切着一刀
f[i]=min(f[j]+1,f[i]);
}//每次判断在j处切一刀,j+1到i能否构成回文
printf("%d\n",f[l1-1]);
}
return 0;
}//首次自己写出崭新的动归,好开森!
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[20010],v[50],n,m;
int main()
{
int i,j;
scanf("%d%d",&m,&n);
for (i=1;i<=n;i++)
scanf("%d",&v[i]);
for (i=1;i<=n;i++)
for (j=m;j>=v[i];j--)
if (f[j-v[i]]+v[i]<=m)
f[j]=max(f[j],f[j-v[i]]+v[i]);
printf("%d",m-f[m]);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[15][15],f[15][15][15][15],n;
int main()
{
int i,j,l,k;
int x,y,z;
scanf("%d",&n);
while (scanf("%d%d%d",&x,&y,&z)==3&&x!=0&&y!=0&&z!=0)
a[x][y]=z;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
for (l=1;l<=n;l++)
for (k=1;k<=n;k++)
if (i!=l&&j!=k)
{
f[i][j][l][k]=max(f[i-1][j][l-1][k]+a[i][j]+a[l][k],f[i][j][l][k]);
f[i][j][l][k]=max(f[i-1][j][l][k-1]+a[i][j]+a[l][k],f[i][j][l][k]);
f[i][j][l][k]=max(f[i][j-1][l-1][k]+a[i][j]+a[l][k],f[i][j][l][k]);
f[i][j][l][k]=max(f[i][j-1][l][k-1]+a[i][j]+a[l][k],f[i][j][l][k]);
}
else
{
f[i][j][l][k]=max(f[i-1][j][l-1][k]+a[i][j],f[i][j][l][k]);
f[i][j][l][k]=max(f[i-1][j][l][k-1]+a[i][j],f[i][j][l][k]);
f[i][j][l][k]=max(f[i][j-1][l-1][k]+a[i][j],f[i][j][l][k]);
f[i][j][l][k]=max(f[i][j-1][l][k-1]+a[i][j],f[i][j][l][k]);
}
printf("%d",f[n][n][n][n]);
return 0;
}
(方格取数还有2、3进阶版。。。但不是用dp做了)#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[210][20],n,k;
int main()
{
int i,j;
scanf("%d%d",&n,&k);
f[0][0]=1;
for (i=1;i<=n;i++)
for (j=1;j<=k;j++)
if (i>=j)
f[i][j]=f[i-j][j]+f[i-1][j-1];
printf("%d",f[n][k]);
return 0;
}//分情况,①不含一份为1的情况,就将i个1先分为j份,再将剩下的分为j份;②至少有一份为1的情况,将剩下的i-1个1分为j-1份;
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int r,c,a[110][110],f[110][110],ans,maxn=0;
int search(int x,int y)
{
if (f[x][y]!=0) return f[x][y];
if (x-1>0&&a[x-1][y]>a[x][y])
f[x][y]=max(f[x][y],search(x-1,y)+1);
if (x+1<=r&&a[x+1][y]>a[x][y])
f[x][y]=max(f[x][y],search(x+1,y)+1);
if (y-1>0&&a[x][y-1]>a[x][y])
f[x][y]=max(f[x][y],search(x,y-1)+1);
if (y+1<=c&&a[x][y+1]>a[x][y])
f[x][y]=max(f[x][y],search(x,y+1)+1);
return f[x][y];
}
int main()
{
int i,j,n,m;
scanf("%d%d",&r,&c);
for (i=1;i<=r;i++)
for (j=1;j<=c;j++)
{
scanf("%d",&a[i][j]);
}
for (i=1;i<=r;i++)
for (j=1;j<=c;j++)
search(i,j);
for (i=1;i<=r;i++)
for (j=1;j<=c;j++)
if (f[i][j]>maxn)
maxn=f[i][j];
printf("%d",maxn+1);
return 0;
}
[持续更新ing]
既然无能更改,又何必枉自寻烦忧