• POJ 2923 Relocation


    题目大意:有n个物品,有两辆车载重分别是c1,c2.问需要多少趟能把物品运完。 (1 ≤ Ci ≤ 100,1 ≤ n ≤ 10,1 ≤ wi ≤ 100).

    题解:n小思状压。我们先把所有一次可以拉走的状态ini预处理好,然后把这些状态当做一个个物品跑背包就行了。

    合并的转移:dp[j|ini[i]]=min(dp[j|ini[i]],dp[j]+1);

    就是如果状态j与ini[i]不冲突,则可以从状态j运一趟变为j|ok[i]。

    然后正确性可以YY一下:为什么可以看成是物品?并一下就可以?是因为ini中包含了所有的可能情况,我们也全都考虑了转移(这句话看不懂就算了我语文不好= =)

    注意几个细节:在check的时候随时注意sm剪枝,f的边界是f[0]=true(无论c1,c2是多少重为0的东西总是可以的),dp的边界是dp[0]=0(全都不搬运能收获0),还有注意判重。然后就差不多了。

    不过我还有个问题:为什么inf=-1u>>1就一直爆?

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 using namespace std;
    10 const int maxn=1<<11,maxv=100+10,inf=1<<30;
    11 int w[10],n,c1,c2,dp[maxn],ini[maxn];
    12 bool check(int val){
    13     static bool f[maxv];memset(f,false,sizeof(f));f[0]=true;
    14     int sm=0;
    15     for(int i=0;i<n;i++) if((1<<i)&val){
    16         sm+=w[i];if(sm>c1+c2) return false;
    17         for(int j=c1;j>=w[i];j--) f[j]=f[j]|f[j-w[i]];
    18     }
    19     for(int i=0;i<=c1;i++) if(f[i]&&sm-i<=c2) return true;
    20     return false;
    21 }
    22 inline int read(){
    23     int x=0,sig=1;char ch=getchar();
    24     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    25     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    26     return x*=sig;
    27 }
    28 inline void write(int x){
    29     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    30     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    31     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    32 }
    33 void init(){
    34     int Case=read();
    35     for(int cas=1;cas<=Case;cas++){
    36         n=read();c1=read();c2=read();
    37         for(int i=0;i<n;i++) w[i]=read();
    38         int cnt=0,num=1<<n;
    39         for(int i=0;i<num;i++){
    40             dp[i]=inf;
    41             if(check(i)) ini[cnt++]=i;
    42         }
    43         dp[0]=0;
    44         for(int i=0;i<cnt;i++)
    45             for(int j=0;j<num;j++) if(!(ini[i]&j))
    46                 dp[ini[i]|j]=min(dp[ini[i]|j],dp[j]+1);
    47         printf("Scenario #%d:
    %d
    
    ",cas,dp[(1<<n)-1]);
    48     }
    49     return;
    50 }
    51 void work(){
    52     return;
    53 }
    54 void print(){
    55     return;
    56 }
    57 int main(){init();work();print();return 0;}
  • 相关阅读:
    Java18(泛型,反射,内省)
    Java17(线程池、Runnable和Callable、Lock、信号量、任务调度、Timer)
    Javaday16(守护线程,线程同步,线程通讯)
    面试题错题集04(异常)
    面试题错题集03(数组)
    面试题错题集02(面向对象)
    Javaday15(Queue,Collections工具类,多线程)
    Java中的内部接口
    ISO14229:2013 之 通过标志读数据ReadDataByIdentifier (0x22)
    Oracle数据库迁移至PostgreSQL数据库问题及解决
  • 原文地址:https://www.cnblogs.com/chxer/p/4573545.html
Copyright © 2020-2023  润新知