由于以下题目过于水,所以合并一起。。
先来个纯模板题。。HDU 1028 Ignatius and the Princess III 完全的模板。。
#include <iostream>
using namespace std;
int c1[1000],c2[1000];
int main()
{
int n;
int i,j,k;
while(cin>>n)
{
for(i=0;i<=n;i++)
{
c1[i]=1;c2[i]=0;
}
for(i=2;i<=n;i++)
{
for(j=0;j<=n;j++)
for(k=0;k<=n;k+=i)
c2[j+k]+=c1[j];
for(j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
cout<<c1[n]<<endl;
}
return 0;
}
HDU 1284 钱币兑换问题 也是模板题,,但是要注意的是,不能把N带入,,不然会TLE,,题目说了上限了,,所以可以先模拟出来。。再求。。
#include <iostream>
using namespace std;
int c1[32768],c2[32768];//题目给的上限。。
int main()
{
int n,i,j,k;
for(i=0;i<=32767;i++)
{
c1[i]=1;
c2[i]=0;
}
for(i=2;i<=3;i++)//只有三种钱币。。
{
for(j=0;j<=32767;j++)
for(k=0;k+j<=32767;k+=i)
{
c2[j+k]+=c1[j];
}
for(j=0;j<=32767;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
while(scanf("%d",&n)!=EOF)
{
cout<<c1[n]<<endl;
}
return 0;
}
HUD 1398 Square Coins 只要注意它的硬币是以平方增长的。。
#include <iostream>
int c1[10001],c2[10001];
using namespace std;
int main()
{
int n,i,j,k;
while(cin>>n)
{
if(n==0)break;
for(i=0;i<=n*n;i++)//第一个要注意的地方。。
{
c1[i]=1;
c2[i]=0;
}
for(i=2;i<=n;i++)
{
for(j=0;j<=n;j++)
for(k=0;k<=n;k+=i*i)//第二个要注意的地方,,因为是平方增长的,所以就是k+=i*i;
c2[j+k]+=c1[j];
for(j=0;j<=n;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
cout<<c1[n]<<endl;
}
return 0;
}
HDU 2082 找单词。。
#include <iostream>
using namespace std;
int c1[1500],c2[1500];
int a[28];
int main()
{
int N;
int i,j,k;
while(cin>>N)
{
for(int h=0;h<N;h++)
{
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(i=1;i<=26;i++)
cin>>a[i];
for(i=0;i<=50&&i<=a[1];i++)//把单词的价值看成是钱,这样会比较好理解。最多不能超过50块。。
c1[i]=1;
for(i=2;i<=26;i++)
{
for(j=0;j<=50;j++)
for(k=0;k+j<=50&&k<=i*a[i];k+=i)//两个指数相加也不能超过50,k不能超过的是第I个字母的价值乘以它的个数
c2[j+k]+=c1[j];
for(j=0;j<=50;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
int sum=0;
for(i=1;i<=50;i++)//把价值从一到50的单词数加起来就是答案了。。
{
sum+=c1[i];
}
cout<<sum<<endl;
}
}
return 0;
}
HDU 1171 Big Event in HDU
//又是一题母函数的经典应用。。
//题意给出N种设备,分别给出设备的价值和数量。。叫你求出分成两半价值相差最小的分发,
//如果不能平分的话就先给出大的。。
#include <iostream>
using namespace std;
int c1[250001],c2[250001];//这里不能开太小不然胡RTE。。
int value[55],amount[55];//这里不能开太大不然会超时。。
int main()
{
int n;
int i,j,k;
while(scanf("%d",&n)!=EOF&&n>0)
{
memset(value,0,sizeof(value));
memset(amount,0,sizeof(amount));
int sum=0;
for(i=1;i<=n;++i)
{
scanf("%d %d",&value[i],&amount[i]);
sum+=value[i]*amount[i];
}
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(i=0;i<=value[1]*amount[1];i+=value[1])//初始化。。就是第一个表达式。。
c1[i]=1;
int len=value[1]*amount[1];
for(i=2;i<=n;i++)
{
for(j=0;j<=len;j++)
for(k=0;k<=value[i]*amount[i];k+=value[i])
c2[k+j]=c1[j];
len+=value[i]*amount[i];//每次要增加的长度。。
for(j=0;j<=len;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
for(i=sum/2;i>=0;--i)//从中间往下,就肯定是从大到小。。
if(c1[i]!=0)
{
printf("%d %d\n",sum-i,i);
break;
}
}
return 0;
}
HDU 2152 Fruit
//中文的题目就不在说了。。就是上下界母函数。。
#include <iostream>
using namespace std;
int c1[10001],c2[10001],a[101],b[101];
int main()
{
int N,M;
int i,j,k;
while(scanf("%d%d",&N,&M)!=EOF)
{
for(i=1;i<=N;i++)
cin>>a[i]>>b[i];
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(i=a[1];i<=b[1];i++)//注意这里的变化。。因为最少要买a[1]个,最多能买b[1]个。。
{
c1[i]=1;
}
for(i=2;i<=N;i++)
{
for(j=0;j<=M;j++)
for(k=a[i];k<=b[i]&&j+k<=M;k++)//这里也是一样的。。因为最少要买a[i]个,最多能买b[i]个。。而且加起来不能超过M。。
c2[j+k]+=c1[j];
for(j=0;j<=M;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
cout<<c1[M]<<endl;
}
return 0;
}