3章第一节有道题敲不出来啊~~~没办法,只能把后面的题先给敲咯~
这个题呢...
首先本巨菜想了一个很傻很水很烂的DP方程。使得自己的程序果断崩了...
开了一个10001*200的二维boolean数组,[面额][张数]这样来DP,因为最大的面额只有10000 ,再通过循环数组的方法,勉强使得空间不爆掉,结果过了9个点,第10个点果断超时。
后来牌桌子一想!可以变成一维DP!a[面额]保存的值为最小张数;
a[i]=min( a[i],a[i-面额]+1 );
这样就很好的A掉了。速度还行。
/* ID:bysen LANG:C++ PROG:stamps */ #include<stdio.h> #define INF 0x0FFFFFFF using namespace std; int re[10001]; //DP数组记录构成当前面额最小的邮票枚数 int v[201]; int min( int a,int b ){ return a<b?a:b; } int main() { freopen( "stamps.in","r",stdin ); freopen( "stamps.out","w",stdout ); int k,n; for( int i=0;i<10001;i++ ) re[i]=INF; scanf( "%d %d",&k,&n ); for( int i=0;i<n;i++ ) { scanf( "%d",&v[i] ); re[v[i]]=1; } int top=v[0]; while( true ) { top++; if( top>10001 ) re[top%10001]=INF; for( int i=0;i<n;i++ ) if( top-v[i]>0 ) re[top%10001]=min( re[top%10001],re[(top-v[i]+10001)%10001]+1 ); if( re[top%10001]>k ) break; } printf( "%d\n",top-1 ); return 0; }