D5

今天的题目跟前几天的比起来简单了许多

由于T1没有开long long 所以T1全部WA掉了...只悲催的A了第二题

T1:多重背包

其实这一题我真心不会,DP各种弱,简直欲哭无泪...

不过认真的看了会儿书,算是领会了些什么吧

晚上跟我室友讲解了一遍,竟然神奇的全明白了...瞬间开森起来

代码+解释:

#include<cstdio>
#include<cstring>
using namespace std;
long long v[2100][2100],n,m,a[2001],b[2001],f[2100][2001],min;
//v是表示所用的时间;
//f[i][j]是表示前i个课题选j个论文所用的最短时间; 
long long p(int x,int y){
	long long s=1;
	for(int i=1;i<=y;i++) s*=x;
	return s;
}
int main(){
	//freopen("problem.in","r",stdin);freopen("problem.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&a[i],&b[i]);
	}
    for(int i=1;i<=n;i++)
        f[1][i]=a[1]*p(i,b[1]);//从前一个状态推下去,把f[i][j]初始化为选第一种课题写i篇论文所用的时间; 
    for(int i=2;i<=m;i++){//枚举前i个课题 
       for(int j=1;j<=n;j++){//共写了j篇论文 
          min=f[i-1][j];
          for(int k=1;k<=j;k++){//当前的第i个课题所写的论文数 
          	 if(min>f[i-1][j-k]+a[i]*p(k,b[i]))//f[i-1][j-k]表示,i-1个课题所写的论文;然后再加上当前课题写的论文数 
          	  min=f[i-1][j-k]+a[i]*p(k,b[i]);
          }
		  f[i][j]=min;//最后记得赋值 
	   }
	}
    printf("%lld",f[m][n]);
    return 0;
}

 MARK...记得注意数据规模..

以及用long long 的时候,记得用上lld...(哲熊说有可能会出现编译器问题,建议我用cout)

 

T2:数论

分析之后发现,数大的那个人%4==0,那么数小的那个人胜...反之,如果有余数,即数大的人胜

#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
int main(){
	freopen("robotb.in","r",stdin);
	freopen("robotb.out","w",stdout);
	for(int i=1;i<=10;i++){
		scanf("%d%d",&n,&m);
		if(n<m){
			if(m%4==0) printf("1\n");
			else printf("2\n");
		}
		else{
			if(n%4==0) printf("2\n");
			else printf("1\n");
		}
	}
	return 0;
}

 

 

T3:单源最短路Dijkstra

算是学了把两种单源最短路的算法都学到了吧...

还有一种是spfa..

对了我上次特地对比了一下spfa和BFS..发现他们的不同之处就在于spfa有记录下他们的距离...

就类似于

if(f[a]+f[b]<f[t]) f[t]=f[a]+f[b]

这样的记录

现在仔细想想dijkstra和spfa有很多相似之处,就比如都需要记录下最短的距离..以及都需要一个bool数组,记录他有没有入队吧..

附上自己程序和自己理解

PS:不懂为什么自己程序照着某位大神的程序改的,居然在计算方案数上貌似错了...希望自己某天再看的时候可以发现吧

#include<cstdio>
#include<cstring>
using namespace std;
int n,m,x,y,f[1001],z,tree[1001][1001],min=123456789;
int size[1001],p=0,t;
bool b[1001]; 
int main(){
	//freopen("syrup.in","r",stdin);freopen("syrup.out","w",stdout);
	freopen("data.txt","r",stdin);
	memset(b,false,sizeof(b));
	scanf("%d",&n);
	for(int i=1;i<=n;i++){//一个小细节注意一下:这里的药水号数是从0开始的,但是为了不乱掉从1开始读入; 
		scanf("%d",&f[i]);
		size[i]=1;
	}
	while(scanf("%d%d%d",&x,&y,&t)!=EOF){
		x++; //也就是上面的注解 
		y++;
		t++;
		tree[x][y]=t;//存图 
		tree[y][x]=t;
	}
	for(int i=1;i<=n;i++){
		min=123456789;
        for(int j=1;j<=n;j++){
        	if(!b[j] && f[j]<min){
        		min=f[j];//记录最小的 
        		p=j;//p记录第几号药水 
        	}
        }
        if(min==123456789 || p==0) break;
        b[p]=1;//记录他已经找过了 
        for(int j=1;j<=n;j++){
        	if(tree[p][j]!=0){
        		t=tree[p][j];
        		if(f[p]+f[j]<f[t]){//dijkstra算法 
        			f[t]=f[p]+f[j];
        			size[t]=0;//个人认为是因为上面的方案不可行..所以附为0;貌似... 
			    }
        	}
        	if(b[j] && f[p]+f[j]==f[t]){
        		size[t]+=size[p]*size[j];
        	}
        }
	}
	printf("%d %d",f[1],size[1]);
	return 0;
}

 再附上AC的程序:

var n,i,j,x,y,t,min,p:longint;
    f,size:array[0..1000] of longint;
    tree:array[0..1000,0..1000] of longint;
    b:array[0..1000] of boolean;

begin
  assign(input,'syrup.in');reset(input);
  assign(output,'syrup.out');rewrite(output);
  readln(n);
  for I:=1 to n do
    begin
      read(f[i]);
      size[i]:=1;
    end;
  while not eof do
    begin
      read(x,y,t);
      inc(x);inc(y);inc(t);
      tree[x,y]:=t;
      tree[y,x]:=t;
    end;

  for i:=1 to n do
    begin
      min:=maxlongint;
      for j:=1 to n do
        begin
          if (not b[j]) and (f[j]<min) then
            begin
              min:=f[j];
              p:=j;
            end;
        end;
      if (min=maxlongint) or (p=0) then exit;
      b[p]:=true;
      for j:=1 to n do
        begin
          if tree[p,j]<>0 then
            begin
              t:=tree[p,j];
              if f[p]+f[j]<f[t] then
                begin
                  f[t]:=f[p]+f[j];
                  size[t]:=0;
                end;
              if (b[j]) and (f[p]+f[j]=f[t]) then
                inc(size[t],size[p]*size[j]);
            end;
        end;
    end;

  writeln(f[1],' ',size[1]);
  close(input);close(output);
end.

 =-=我觉得真的一模一样啊....真奇怪啊...

 

T4:广搜+二分答案..

TAT...依旧没时间改了...惨...我貌似已经累积了好几题了...说多了都是自己弱啊..

 

总之...今天收获不错..学到了许多东西

明天BLESS ALL

转载于:https://www.cnblogs.com/polebug/p/3847785.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值