acm 一周训练总结

一周  总的来说 状压dp + 数学

状压dp 的概念就是 

根据 所选物体的多种状态 将其压缩为一个二进制形式

比如 一行

101 表示1开0关1开  这是一种状态,

dp 找状态转移方程

两种状态不能重合  在选取可以的 逐步dp 我认为 这个过程类似搜索  dfs 逐步找适合的 最后枚举 。

我是看例题

看懂的 这里 

有n门课,每门课有截止时间和完成所需的时间,如果超过规定时间完成,每超过一天就会扣1分,问怎样安排做作业的顺序才能使得所扣的分最小

思路:因为最多只有15门课程,可以使用二进制来表示所有完成的状况

例如5,二进制位101,代表第一门和第三门完成了,第二门没有完成,那么我们可以枚举1~1<<n便可以得出所有的状态

然后对于每一门而言,其状态是t = 1<<i,我们看这门在现在的状态s下是不是完成,可以通过判断s&t是否为1来得到

当得出t属于s状态的时候,我们便可以进行DP了,在DP的时候要记录路径,方便之后的输出

就是这个 例题

状压dp的 内容主要是找状态 

找状态加状态转移方程 

需要注意的 是

n个位置

1<<n 得数是1后面n个0

这是 枚举的关键


a了 8个题就开始搞数学了 

听学长的意见 

这是个组队游戏

还得有人搞数学

高斯消元法

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<cmath>
using namespace std;
double g[1000][1000];
double jie[10000];
int n,m;
void solve()
{
    int i,j;
    int k;
    int s;
    for(i=1;i<=n;i++)
    {
        int r=i;
        for(j=i+1;j<=n;j++)
        {
            if(abs(g[j][i])>abs(g[r][i])) r=j;
        }
         if(r!=i)
          for(s=1;s<=m+1;s++) swap(g[i][s],g[r][s]);
        for(k=i+1;k<=n;k++)
        {
            double f=g[k][i]/g[i][i];
            for(j=1;j<=m+1;j++)
                g[k][j]-=f*g[i][j];
        }
   }
   for(i=1;i<=n;i++)
   {
       cout<<endl;
       for(k=1;k<i;k++)
        cout<<" ";
       for(j=i;j<=m;j++)
        cout<<g[i][j]<<" ";
   }
   cout<<endl;
   for(i=n;i>=1;i--)
   { double sum=g[i][m+1];
       for(j=m;j>=i+1;j--)
         sum-=jie[j]*g[i][j];
      jie[i]=sum/g[i][i];
   }
}
int main()
{

    int i,j;
    while(cin>>n>>m)
    {
      for(i=1;i<=n;i++)
            for(j=1;j<=m+1;j++)
              cin>>g[i][j];
     solve();
    for(i=1;i<=n;i++)
        cout<<jie[i]<<endl;
    }
}
这个是

高斯消元法最经典的 关灯

看了好久看懂了。

学会递推的矩阵快速幂 。

斐波那契数列

就是最经典的矩阵快速幂

#include<iostream>
#include<cstdio>
using namespace std;
int n,a[2][2],b[2][2];
void mul(int a[2][2],int b[2][2],int ans[2][2])
{
     int t[2][2];
     for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        {
                t[i][j]=0;
                for(int k=0;k<2;k++)
                t[i][j]=(t[i][j]+a[i][k]*b[k][j])%10000;
        }
     for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
           ans[i][j]=t[i][j];    
 }
int main()
{
    while(scanf("%d",&n))
    {
        if(n==-1)return 0;
        a[0][0]=a[0][1]=a[1][0]=1;a[1][1]=0;
        b[0][0]=b[1][1]=1;
        b[1][0]=b[0][1]=0;
        while(n)
        {
                if(n&1)mul(a,b,b);
                n>>=1;
                mul(a,a,a);
        } 
        printf("%d\n",b[1][0]); 
    }
}
          


这是斐波那契数列 利用矩阵快速幂 解决方法
 比如
矩阵
AAAAAAAA
可以分成
AAAA
*AAAA
111111111111111111

占一个

矩阵快速幂

欧拉函数

奇妙的容斥原理

同余莫算数

杨辉三角

等等

一个文件夹了整理的

最后一句  矩阵真神奇!!!!!!!!!!!!!!!!!!!!!!



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值