zoukankan      html  css  js  c++  java
  • 昨天的总结

    题意:给定一个自然数N,要求把N拆成若干个正整数相加的形式,整数可重复。拆分的方案数mod取余。

    思路:完全背包裸题,因为整数可重复,N相当于给定的体积。

    f[0]=1;
    for(int i=1;i<=n;i++)
      for(int j=i;j<=n;j++)
        f[j]=(f[j]+f[j-i])%mod;
      

    题意:

    从N个人当中选出M个人作为法官。每个人都有一个ai属性和一个bi属性。现在要要求选出来的这M个人的ai之和与bi之和的差值最小,并且在差值一样的情况下要求输出ai之和与bi之和最大的方案。

    思路

    这个还是从N个人当中选出M个物品的问题,但是现在容量限制有了,但是每个人的价值,体积却没有。由于要求sum(ai) 与sum(bi) 之和最大,所以我们以每个人ai与bi之和作为这个人的价值。以ai与bi之差作为这个人的体积。则 以dp[N][M][k]作为状态,表示的就是从N个人当中选出M个人,这M个人的sum(ai)与sum(bi)之差为k时的总价值。但是这道题问的是方案,所以还要记录每一个状态是由哪一个状态转移而来的。所以用一个和D[i][j][k]来记录,最后在递归返回调用。这里说一个编程技巧,如果下标有负数,就设置一个偏移量,负数用偏移量减去某个数来表示,这样就把负数问题解决了。

    题意:

    给你一个含有N个顶点N条边的规范多变形,每条边的权值是 * '或者 ' + '。' * '代表 这条边两端顶点值相乘,'  +  '代表这条边两端顶点相加。第一步任意删除一条边。之后的N-1步每一次删除一条边,同时这条边的两个顶点做边上符号的运算变换成一个新的顶点。直到最后只剩下一个顶点。   现在问你最后剩下的点最大值可能是多少。

    思路:区间dp,dp的思路就不说了。说几个编程的技巧。1.因为这里相当于是从这个环中任意顺序把 N个点进行合并。可以把N个点排成一条链,然后再这个链的末尾再复制一个同样的链。这里不用真的去复制一个链再后面,只要运用求余符号就可以。比如我要求i点往后m个距离的点j的具体值。则(i+m)%N就可以得到这个点的值了。这种手法经常用在环形dp要求当中。

    2.如果dp的状态,某一个维度的值是有限的,比如只有0,1两个取值,这个时候就 不要用for循环去枚举了,直接dp[][][0].dp[][][1],

    #include<bits/stdc++.h>
    using namespace std;
    const int inf=0x3f3f3f3f;
    char c[55];
    int val[55],dp_max[55][55],dp_min[55][55];
    int cal(char x,int a,int b)
    {
        if(x=='t')
            return a+b;
        return a*b;
    }
    
    int main()
    {
       int n,i,j,k,l,p1,p2,ans,MAX,MIN,sign;
       while(scanf("%d",&n)!=EOF)
       {
           //cin>>c[i]>>val[i];
           for(int i=0;i<n;i++)
              cin>>c[i]>>val[i];
    
           for(int i=0;i<n;i++)
                dp_max[i][i]=dp_min[i][i]=val[i];
           for(int len=1;len<n;len++)
           {
               for(int i=0;i<n;i++)
               {
                   MAX=-inf,MIN=inf;
                   j=(i+len)%n;
                   for(int k=0;k<len;k++)
                   {
                       p1=(i+k)%n;
                       p2=(i+k+1)%n;
                       MAX=max(MAX,cal(c[p2],dp_max[i][p1],dp_max[p2][j]));
                       MAX=max(MAX,cal(c[p2],dp_min[i][p1],dp_min[p2][j]));
                       MIN=min(MIN,cal(c[p2],dp_max[i][p1],dp_max[p2][j]));
                       MIN=min(MIN,cal(c[p2],dp_min[i][p1],dp_min[p2][j]));
                   }
                   dp_max[i][j]=MAX;
                   dp_min[i][j]=MIN;
               }
           }
    
           ans=-inf;
           for(int i=0;i<n;i++){
            j=(i+n-1)%n;
            ans=max(ans,dp_max[i][j]);
           }
    
            cout<<ans<<"
    ";
            for(int i=0;i<n;i++){
                j=(i+n-1)%n;
                if(dp_max[i][j]==ans)
                 cout<<i+1<<" ";
            }
            cout<<"
    ";
       }
       return 0;
    }
  • 相关阅读:
    SecureCRT
    NFS服务器搭建
    卸载oracle步骤
    redhat 5.5 x86_x64搭建samba服务器
    ORA-01940: cannot drop a user that is currently connected
    迁移表空间
    日常SQL使用总结
    DataGuard常规操作命令
    使用PowerDesginer画ER图
    数据库卸载
  • 原文地址:https://www.cnblogs.com/rainyskywx/p/11188511.html
Copyright © 2011-2022 走看看