- P2909 [USACO08OPEN]Cow Cars S
思路
一开始我是这么想的,先给牛的速度排序,然后再根据速度把每头牛依次放到每个道上去。
但有一种更好的方法:排序+统计。就是依次统计每条道上可以放几头牛。
源码
#include<bits/stdc++.h>
using namespace std;
int s[50005];
int main(){
int n,m,d,l;//n头牛,m条道,d表示单位,l最低速度
cin>>n>>m>>d>>l;
for(int i=0;i<n;i++)
cin>>s[i];
sort(s,s+n);
int sum=0;//计算牛的数量
int ans=0;//枚举每条道上,前面的牛数。
for(int i=0;i<m;i++){
ans=0;
for(int j=0;j<n;j++){
if(!s[j]) continue;
if( s[j]-d*ans>=l || (s[j]-d*ans<0&&l==0) ){ //l为0,则所有牛都能放
sum++;
ans++;
s[j] = 0;
}
}
}
cout<<sum<<endl;
return 0;
}
- P1252 马拉松接力赛
思路
求最短时间,就是计算每多跑1km,那个运动员花的时间最少。
源码
#include<bits/stdc++.h>
using namespace std;
int a[5][11],b[5][11];
int c[5];
int flag,ans;
int main(){
for(int i=0;i<5;i++)
c[i]=1;
for(int i=0;i<5;i++){
for(int j=1;j<11;j++){
cin>>a[i][j];
b[i][j]=a[i][j]-a[i][j-1]; //计算时间差,用于计算时间最小值
}
}
for(int i=0;i<20;i++){
int minn=1000000009;
for(int j=0;j<5;j++){
if(b[j][c[j]+1]<minn&&c[j]+1<=10){
flag=j; //flag用于标记,当前最短时间是那个人
minn=b[j][c[j]+1];
}
}
c[flag]++;
}
for(int i=0;i<5;i++){
ans+=a[i][c[i]];
}
cout<<ans<<endl;
for(int i=0;i<5;i++)
cout<<c[i]<<" ";
}
- P1515 旅行
思路
先排序,再用搜索来计算次数。
源码
#include<bits/stdc++.h>
using namespace std;
// 已经有的旅馆列表:
int a[40]={0,990,1010,1970,2030,2940,3060,3930,4060,4970,5030,5990,6010,7000};
int c,b,n,ans;
void dfs(int k)//k:第k个旅馆
{
if(k==n){
ans++;
return ;
}
for(int i=k+1;i<=n;i++){
if(a[i]-a[k]>=c&&a[i]-a[k]<=b){
dfs(i);
}
}
}
int main()
{
cin>>c>>b>>n;
for(int i=14;i<n+14;i++)
cin>>a[i];
n=n+14;
sort(a,a+n+1); //给n个数排序。
dfs(0);
cout<<ans<<endl;
}
思路2
1.一个数组储存所有旅馆,初始化时先存下前面14个旅馆。
2.输入新添加旅馆后,将所有旅馆排序,方便日后比较。
3.根据斐波那契数列,如果可以从A点走到B点,那么A点的总方案数应该加上B点的方案数。
4.循环进行3操作即可(但B点只需要是A点前面的点)。
源码
//刚开始的地方也算,一种方案。
#include<bits/stdc++.h>//超级万能头
using namespace std;
int a,b,n,ans[40],r[40]={0,990,1010,1970,2030,2940,3060,3930,4060,4970,5030,5990,6010,7000};
//旅馆初始化
int main(){
scanf("%d %d %d",&a,&b,&n);
for (int i=14;i<14+n;i++) cin>>r[i];//输入
sort(r,r+14+n);//排序
ans[0]=1; //起始点默认一套方案
for (int i=1;i<14+n;i++){//枚举所有点
for (int j=0;j<i;j++){//枚举这个点之前的点
if (r[i]-r[j]>=a&&r[i]-r[j]<=b){//如果这两个点之间的距离符合要求
ans[i]+=ans[j];//这个点可以获得前面那个点的所有可能
}
}
}
cout<<ans[13+n]<<endl;//输出到终点时的所有可能
return 0;//好习惯不可忘
}
- P2695 骑士的工作
思路
排序+判断
源码
#include <stdio.h>
#include<iostream>
#include <algorithm>//sort头
using namespace std;
int main () {
int qs[20010],el[20010],m,n,i,ans=0;
cin>>n>>m;
for (i=0;i<n;i++) cin>>el[i];//读入,不必多说
for (i=0;i<m;i++) cin>>qs[i];
sort (el,el+n);//排序
sort (qs,qs+m);//排序
if (n>m) {//如果恶龙数大于骑士的数量,则输出you died!
printf ("you died!");
return 0;
}
int j=0;
for (i=0;i<n;i++) {//枚举答案
while (el[i]>qs[j]) j++;//找到最小一个大于该头的骑士
ans+=qs[j];//累加答案
if (j>m-1) break;
j++;
}
if (i!=n)
printf ("you died!");//输出答案
else
printf ("%d\n",ans);
return 0;//好轻松的呢!!!
}
- P1376 [USACO05MAR]Yogurt factory 机器工厂
思路
首先需要想明白一点,委托人需要多少机器,并不意味着每周要生产多少机器。
若上一周的价格比这周的便宜,则可以让上周多生产一点。
若本周便宜,则只需要本周进行生产就行。
继续判断,则需要本周的价格与先前最小的价格判断。
源码
#include<iostream>
using namespace std;
int main()
{
//就是交付完这些机器要花多少钱,多生产不用管。
//这样理解:第一周因为是刚生产则直接卖出,但制造的机器可以大于需要的
//
int c,y;
long long n,ans=0;
int s,lastweek;
cin>>n>>s;
for(int i=1;i<=n;i++)
{
cin>>c>>y; //一台机器的价格,需要交付的机器
if(i==1) lastweek=c; //上一星期每台机器要花的钱
else lastweek=min(lastweek+s,c); // 上星期与这个星期的比较
ans+=lastweek*y;//那个便宜就选哪种方案
}
cout<<ans;
//system("pause");
return 0;
}