分别枚举矩形的上下边,把问题转化为求一维的最大子段。
#include<iostream>
using namespace std;
int arr[105][105];
int n,t[105];
const int inf=100000000;
int maxsubr()
{
    int maxn=-inf,sum=0;
    for(int i=1;i<=n;i++)
    {
        if(sum>0) 
            sum+=t[i];
        else 
            sum=t[i];
        if(maxn<sum)
            maxn=sum;
    }
    return maxn;
}
int main()
{
    int i,j;
    int ans=-inf;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            scanf("%d",&arr[i][j]);
    for(i=1;i<=n;i++)
    {
        memset(t,0,sizeof(t));
        for(j=i;j<=n;j++)
        {
            for(int k=1;k<=n;k++)
            {
                  t[k]+=arr[j][k];
            }
            int temp=maxsubr();
            if(ans<temp) ans=temp;
        }
    }
    printf("%d\n",ans);
    return 0;
}
			posted @ 
2010-08-11 10:19 wuxu 阅读(148) | 
评论 (0) | 
编辑 收藏枚举+贪心
把每钓5分钟鱼称为钓一次鱼。首先枚举John需要走过的池塘的数目X,即从池塘1走到池塘X。减去路上花去的时间T=sum(Ti) i=1...X-1,这样我们可以认为John能从一个池塘"瞬间转移"到另一个池塘,即在任意一个时刻都可以在池塘1到池塘X中任选一个钓一次鱼(很重要)。现在采用贪心策略,每次选择鱼最多的池塘钓一次鱼。对于每个池塘来说,由于在任何时候鱼的数目只和John在该池塘里钓鱼的次数有关,和钓鱼的总次数无关,所以这个策略是最优的。假设一共允许钓k次鱼,那么每次在N个池塘中选择鱼最多的一个钓。总的时间复杂度为O(kn^2)。 在最后的结果中,第一个最大值所对应的在每个池塘的钓鱼时间为题目要求的情况,因为如果John在后面的池塘钓了鱼,那么前面相应的时间就会减少。最后注意池塘中没有鱼的情况。
 #include<iostream>
#include<iostream>
 using namespace std;
using namespace std;
 int n,h,ans;
int n,h,ans;
 int f[26],t[26],d[26];
int f[26],t[26],d[26];
 int main()
int main()


 {
{
 int i,k,total,j=0;
    int i,k,total,j=0;
 int fish[26],time[26],tt[26];
    int fish[26],time[26],tt[26];
 while(scanf("%d",&n)!=EOF&&n)
    while(scanf("%d",&n)!=EOF&&n)

 
     {
{
 scanf("%d",&h);
        scanf("%d",&h);
 h*=12;
        h*=12;
 for(i=1;i<=n;i++) scanf("%d",&f[i]);
        for(i=1;i<=n;i++) scanf("%d",&f[i]);
 for(i=1;i<=n;i++) scanf("%d",&d[i]);
        for(i=1;i<=n;i++) scanf("%d",&d[i]);
 t[1]=0;
        t[1]=0;
 for(i=2;i<=n;i++)
        for(i=2;i<=n;i++)

 
         {
{
 scanf("%d",&t[i]);
            scanf("%d",&t[i]);
 t[i]+=t[i-1];
            t[i]+=t[i-1];
 }
        }
 ans=-1;
        ans=-1;
 for(i=1;i<=n;i++)
        for(i=1;i<=n;i++)

 
         {
{
 total=0;
            total=0;
 int remain=h-t[i];
            int remain=h-t[i];
 memcpy(fish,f,sizeof(f));
            memcpy(fish,f,sizeof(f));
 memset(tt,0,sizeof(tt));
            memset(tt,0,sizeof(tt));
 while(remain>0)
            while(remain>0)

 
             {
{
 int maxn=-1,cur=-1;
                int maxn=-1,cur=-1;
 for(k=1;k<=i;k++)
                for(k=1;k<=i;k++)

 
                 {
{
 if(fish[k]>maxn)
                    if(fish[k]>maxn)

 
                     {
{
 maxn=fish[k];
                        maxn=fish[k];
 cur=k;
                        cur=k;
 }
                    }
 }
                }
 total+=maxn;
                total+=maxn;
 fish[cur]-=d[cur];
                fish[cur]-=d[cur];
 if(fish[cur]<0) fish[cur]=0;
                if(fish[cur]<0) fish[cur]=0;
 tt[cur]+=5;
                tt[cur]+=5;
 remain--;
                remain--;
 }
            }
 if(total>ans)
            if(total>ans)

 
             {
{
 ans=total;
                ans=total;
 memcpy(time,tt,sizeof(tt));
                memcpy(time,tt,sizeof(tt));
 }
            }
 }
        }
 if(j) printf("\n");
        if(j) printf("\n");
 j=1;
        j=1;
 for(i=1;i<=n;i++)
        for(i=1;i<=n;i++)

 
         {
{
 if(i==n) printf("%d \n",time[i]);
            if(i==n) printf("%d \n",time[i]);
 else printf("%d, ",time[i]);
            else printf("%d, ",time[i]);
 }
        }
 printf("Number of fish expected: %d\n",ans);
        printf("Number of fish expected: %d\n",ans);
 }
    }
 return 0;
    return 0;
 }
}

posted @ 
2010-08-10 20:13 wuxu 阅读(273) | 
评论 (0) | 
编辑 收藏
			     摘要: 刚学编程的时候写的,留下来做个纪念。一、初步设计1、新建工程slidwindow,在MFC的向导第一步选择Single Document,按Finish结束。2、选择ResourceView窗口,打开菜单编辑器,在顶层菜单上添加“开始”和“单步”菜单,其ID分别为ID_START_SLIDWIND和ID_TRACE_SLIDWIND,在 &...  
阅读全文
			posted @ 
2010-08-10 00:20 wuxu 阅读(1496) | 
评论 (0) | 
编辑 收藏做该题的时候,看了网上另外一个版本的递推关系,不过还是朴素一点的比较好理解.状态转移方程为:
f[i,j]=max{f[i-1,j-1],f[i-1,j],f[i-1,j+1]}+w(i,j), 其中f[i,j]表示第i 秒 ,门开放度为j 时的最大加分.w(i,j)表示在该状态下的所有加分.为防止超内存用滚动数组.(由于不仔细把1写成了i,调试了半天,杯具了~~)  详细见代码:
#include<iostream>
#include<algorithm>
using namespace std;
int f[2][102];
int hash[30002];
int N,K,T,ans;
typedef struct 
{
    int t,p,s;
}Gant;
Gant s[102];
int cmp(Gant a,Gant b)
{
   if(a.t<b.t) return 1;
   else if(a.t==b.t)
   {
       if(a.s<b.s) return 1;
   }
   return 0;
}
int main()
{
    int i,j,k;
    scanf("%d%d%d",&N,&K,&T);
    for(i=1;i<=N;i++) scanf("%d",&s[i].t);
    for(i=1;i<=N;i++) scanf("%d",&s[i].p);
    for(i=1;i<=N;i++) scanf("%d",&s[i].s);
    memset(hash,0,sizeof(hash));
    memset(f,-1,sizeof(f));
    for(i=1;i<=N;i++) hash[s[i].t]=1;
    sort(s+1,s+N+1,cmp);
    f[0][0]=0;
    ans=0;
    for(i=1;i<=T;i++)
        for(j=0;j<=K;j++)
        {
            int w=0;
            if(hash[i])
            {
                for(k=1;k<=N;k++)
                    if(s[k].t==i&&s[k].s==j)
                        w+=s[k].p;
            }
            if(j>=1&&f[(i-1)&1][j-1]!=-1&&f[i&1][j]<f[(i-1)&1][j-1]+w)
                f[i&1][j]=f[(i-1)&1][j-1]+w;
            if(j+1<=K&&f[(i-1)&1][j+1]!=-1&&f[i&1][j]<f[(i-1)&1][j+1]+w)
                f[i&1][j]=f[(i-1)&1][j+1]+w;
            if(f[(i-1)&1][j]!=-1&&f[i&1][j]<f[(i-1)&1][j]+w)
                f[i&1][j]=f[(i-1)&1][j]+w;
            if(ans<f[i&1][j]) ans=f[i&1][j];
        }
    printf("%d\n",ans);
    return 0;
}
			posted @ 
2010-08-09 17:43 wuxu 阅读(167) | 
评论 (0) | 
编辑 收藏一道很经典的DP,状态转移方程为:f[i,j,k]=max{f[i-1,j,k],f[i-1,j-1,k-(p[i]-d[i])]+p[i]+d[i]}。其中f[i,j,k]表示在前i个候选人中选择j个人,并且辩控差为k时的最大辩控和。另外用path[i,j,k]来记录路径,表示当前方案下选择的最后一个人。详细见代码:
 #include<iostream>
#include<iostream>
 #include<stack>
#include<stack>
 using namespace std;
using namespace std;
 int n,m,test;
int n,m,test;
 int p[205],d[205];
int p[205],d[205];
 int f[205][25][805];
int f[205][25][805];
 int path[205][25][805];
int path[205][25][805];
 int main()
int main()


 {
{
 test=0;
    test=0;
 while(scanf("%d%d",&n,&m)!=EOF&&(m||n))
    while(scanf("%d%d",&n,&m)!=EOF&&(m||n))

 
     {
{
 int i,j,k;
        int i,j,k;
 for(i=1;i<=n;i++)
        for(i=1;i<=n;i++)
 scanf("%d%d",&p[i],&d[i]);
            scanf("%d%d",&p[i],&d[i]);
 int mid=m*20;
        int mid=m*20;
 memset(f,-1,sizeof(f));
        memset(f,-1,sizeof(f));
 memset(path,-1,sizeof(path));
        memset(path,-1,sizeof(path));
 for(i=0;i<=n;i++) f[i][0][mid]=0;
        for(i=0;i<=n;i++) f[i][0][mid]=0;
 for(i=1;i<=n;i++)
        for(i=1;i<=n;i++)
 for(j=1;j<=m&&j<=i;j++)
            for(j=1;j<=m&&j<=i;j++)
 for(k=0;k<=2*mid;k++)
                for(k=0;k<=2*mid;k++)

 
                 {
{
 f[i][j][k]=f[i-1][j][k];
                    f[i][j][k]=f[i-1][j][k];
 path[i][j][k]=path[i-1][j][k];
                    path[i][j][k]=path[i-1][j][k];
 if(k>=p[i]-d[i]&&k-(p[i]-d[i])<=2*mid
                    if(k>=p[i]-d[i]&&k-(p[i]-d[i])<=2*mid
 &&f[i-1][j-1][k-(p[i]-d[i])]!=-1
                        &&f[i-1][j-1][k-(p[i]-d[i])]!=-1
 &&f[i][j][k]<=f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i])
                        &&f[i][j][k]<=f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i])

 
                     {
{
 f[i][j][k]=f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i];
                        f[i][j][k]=f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i];
 path[i][j][k]=i;
                        path[i][j][k]=i;
 }
                    }
 }
                }
 i=0;
        i=0;
 int conc;
        int conc;
 while(i<=mid)
        while(i<=mid)

 
         {
{
 if(f[n][m][mid+i]!=-1||f[n][m][mid-i]!=-1)
            if(f[n][m][mid+i]!=-1||f[n][m][mid-i]!=-1)
 break;
                break;
 i++;
            i++;
 }
        }
 if(f[n][m][mid+i]>f[n][m][mid-i])
        if(f[n][m][mid+i]>f[n][m][mid-i])
 conc=mid+i;
            conc=mid+i;
 else conc=mid-i;
        else conc=mid-i;
 int prose=0,def=0;
        int prose=0,def=0;
 stack<int> ss;
        stack<int> ss;
 i=path[n][m][conc];
        i=path[n][m][conc];
 j=m;
        j=m;
 while(i!=-1)
        while(i!=-1)

 
         {
{
 prose+=p[i];
            prose+=p[i];
 def+=d[i];
            def+=d[i];
 ss.push(i);
            ss.push(i);
 j=j-1;
            j=j-1;
 conc-=(p[i]-d[i]);
            conc-=(p[i]-d[i]);
 i=path[i-1][j][conc];
            i=path[i-1][j][conc];
 }
        }
 printf("Jury #%d\n",++test);
        printf("Jury #%d\n",++test);
 printf("Best jury has value %d for prosecution and value %d for defence:\n",prose,def);
        printf("Best jury has value %d for prosecution and value %d for defence:\n",prose,def);
 while(!ss.empty())
        while(!ss.empty())

 
         {
{
 printf(" %d",ss.top());
            printf(" %d",ss.top());
 ss.pop();
            ss.pop();
 }
        }
 printf("\n\n");
        printf("\n\n");
 }
    }
 return 0;
    return 0;
 }
}



posted @ 
2010-08-09 01:16 wuxu 阅读(271) | 
评论 (0) | 
编辑 收藏首先建一个虚结点,权值为无穷大.  将入度为0的点与之相连, 然后做树形DP,为了防止重复,父亲单独考虑.详细见代码:
 #include<iostream>
#include<iostream>
 #include<vector>
#include<vector>
 #include<map>
#include<map>
 #include<string>
#include<string>
 #include<sstream>
#include<sstream>
 using namespace std;
using namespace std;

 const int inf=1000000000;
const int inf=1000000000;

 vector<int> G[210];
vector<int> G[210];
 int dp[210][210];
int dp[210][210];
 int cost[210],in_degree[210];
int cost[210],in_degree[210];
 bool vis[210];
bool vis[210];
 int n,m;
int n,m;

 int min(int a,int b)
int min(int a,int b)


 {
{
 return a<b?a:b;
     return a<b?a:b;
 }
}

 int dfs(int u)
int dfs(int u)


 {
{
 int i,j,k,v;
     int i,j,k,v;
 int num=1;
     int num=1;
 vis[u]=1;
     vis[u]=1;
 dp[u][0]=0;
     dp[u][0]=0;
 for(i=0;i<G[u].size();i++)
     for(i=0;i<G[u].size();i++)

 
      {
{
 v=G[u][i];
         v=G[u][i];
 if(vis[v]) continue;
         if(vis[v]) continue;
 num+=dfs(v);
         num+=dfs(v);
 }
     }
 for(i=0;i<G[u].size();i++)
     for(i=0;i<G[u].size();i++)

 
      {
{
 v=G[u][i];
         v=G[u][i];
 for(j=n;j>=0;j--)
         for(j=n;j>=0;j--)
 for(k=1;k<=n;k++)
         for(k=1;k<=n;k++)

 
          {
{
 if(j>=k&&dp[u][j]!=-1&&dp[u][j-k]!=-1&&dp[v][k]!=-1)
              if(j>=k&&dp[u][j]!=-1&&dp[u][j-k]!=-1&&dp[v][k]!=-1)
 dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]);
                 dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]);
 else if(j>=k&&dp[u][j]==-1&&dp[u][j-k]!=-1&&dp[v][k]!=-1)
              else if(j>=k&&dp[u][j]==-1&&dp[u][j-k]!=-1&&dp[v][k]!=-1)
 dp[u][j]=dp[u][j-k]+dp[v][k];
                  dp[u][j]=dp[u][j-k]+dp[v][k];
 }
         }
 }
     }
 if(dp[u][num]!=-1&&dp[u][num]>cost[u])
     if(dp[u][num]!=-1&&dp[u][num]>cost[u])
 dp[u][num]=cost[u];
        dp[u][num]=cost[u];
 else if(dp[u][num]==-1) dp[u][num]=cost[u];
     else if(dp[u][num]==-1) dp[u][num]=cost[u];
 return num;
     return num;
 }
}

 int main()
int main()


 {
{
 int i,j;
    int i,j;
 char str[1000];
    char str[1000];
 while(gets(str))
    while(gets(str))

 
     {
{
 if(str[0]=='#') break;
        if(str[0]=='#') break;
 sscanf(str,"%d%d",&n,&m);
        sscanf(str,"%d%d",&n,&m);
 for(i=0;i<=n;i++) G[i].clear();
        for(i=0;i<=n;i++) G[i].clear();
 map<string,int>graph;
        map<string,int>graph;
 memset(in_degree,0,sizeof(in_degree));
        memset(in_degree,0,sizeof(in_degree));
 int id=0;
        int id=0;
 for(i=1;i<=n;i++)
        for(i=1;i<=n;i++)

 
         {
{
 scanf("%s",str);
            scanf("%s",str);
 if(graph.find(str)==graph.end()) graph[str]=++id;
            if(graph.find(str)==graph.end()) graph[str]=++id;
 int u=graph[str];
            int u=graph[str];
 scanf("%d",&cost[u]);
            scanf("%d",&cost[u]);
 gets(str);
            gets(str);
 stringstream ss(str);
            stringstream ss(str);
 string name;
            string name;
 while(ss>>name)
            while(ss>>name)

 
             {
{
 if(graph.find(name)==graph.end()) graph[name]=++id;
                if(graph.find(name)==graph.end()) graph[name]=++id;
 G[u].push_back(graph[name]);
                G[u].push_back(graph[name]);
 in_degree[graph[name]]++;
                in_degree[graph[name]]++;
 }
            }
 }
        }
 cost[0]=inf;
       cost[0]=inf;
 for(i=1;i<=n;i++)
       for(i=1;i<=n;i++)

 
        {
{
 if(in_degree[i]) continue;
            if(in_degree[i]) continue;
 G[0].push_back(i);
            G[0].push_back(i);
 }
       }
 memset(vis,0,sizeof(vis));
       memset(vis,0,sizeof(vis));
 memset(dp,-1,sizeof(dp));
       memset(dp,-1,sizeof(dp));
 dfs(0);
       dfs(0);
 int ans=inf;
       int ans=inf;
 for(j=m;j<=n;j++)
       for(j=m;j<=n;j++)
 if(dp[0][j]!=-1&&dp[0][j]<ans)
       if(dp[0][j]!=-1&&dp[0][j]<ans)
 ans=dp[0][j];
       ans=dp[0][j];
 printf("%d\n",ans);
       printf("%d\n",ans); 
 }
    }
 //system("pause");
    //system("pause");
 return 0;
    return 0;
 }
}



posted @ 
2010-08-07 15:03 wuxu 阅读(168) | 
评论 (0) | 
编辑 收藏
			     摘要: 树形背包。代码如下:
#include<iostream>#include<vector>using namespace std;int n,m;int num[105],brain[105];int dp[105][105];int vis[105];vector<int> map[105...  
阅读全文
			posted @ 
2010-08-07 01:25 wuxu 阅读(1360) | 
评论 (0) | 
编辑 收藏依赖背包(树形背包)。见代码:
 #include<iostream>
#include<iostream>
 #include<vector>
#include<vector>
 using namespace std;
using namespace std;
 int N,M;
int N,M;
 int val[205];
int val[205];
 int vis[205];
int vis[205];
 int f[205][205];
int f[205][205];
 int dp[205][205];
int dp[205][205];
 vector<int> tree[205];
vector<int> tree[205];

 int max(int a,int b)
int max(int a,int b)


 {
{
 return a>b?a:b;
    return a>b?a:b;
 }
}

 void dfs(int x)
void dfs(int x)


 {
{
 int i,j,k;
    int i,j,k;
 vis[x]=1;
    vis[x]=1;
 dp[x][0]=0;
    dp[x][0]=0;
 f[x][0]=0;
    f[x][0]=0;

 for(i=0;i<tree[x].size();i++)
    for(i=0;i<tree[x].size();i++)
 for(j=M;j>=0;j--)
        for(j=M;j>=0;j--)

 
         {
{
 int temp=tree[x][i];
            int temp=tree[x][i];
 if(!vis[temp]) dfs(temp);
            if(!vis[temp]) dfs(temp);
 for(k=0;k<=M;k++)
            for(k=0;k<=M;k++)

 
             {
{
 if(dp[temp][k]!=-1&&j>=k&&f[x][j-k]!=-1)
                if(dp[temp][k]!=-1&&j>=k&&f[x][j-k]!=-1)
 f[x][j]=max(f[x][j],f[x][j-k]+dp[temp][k]);
                    f[x][j]=max(f[x][j],f[x][j-k]+dp[temp][k]);
 }
            }
 }
        }
 for(i=1;i<=M+1;i++)
    for(i=1;i<=M+1;i++)
 if(f[x][i-1]!=-1) dp[x][i]=f[x][i-1]+val[x];
        if(f[x][i-1]!=-1) dp[x][i]=f[x][i-1]+val[x];
 }
}

 int main()
int main()


 {
{
 while(scanf("%d%d",&N,&M)!=EOF&&(N||M))
    while(scanf("%d%d",&N,&M)!=EOF&&(N||M))

 
     {
{
 int i,a,b;
        int i,a,b;
 for(i=0;i<=N;i++)
        for(i=0;i<=N;i++)
 tree[i].clear();
            tree[i].clear();
 for(i=1;i<=N;i++)
        for(i=1;i<=N;i++)

 
         {
{
 scanf("%d%d",&a,&b);
            scanf("%d%d",&a,&b);
 tree[a].push_back(i);
            tree[a].push_back(i);
 val[i]=b;
            val[i]=b;
 }
        }

 val[0]=0;
        val[0]=0;
 memset(vis,0,sizeof(vis));
        memset(vis,0,sizeof(vis));
 memset(dp,-1,sizeof(dp));
        memset(dp,-1,sizeof(dp));
 memset(f,-1,sizeof(f));
        memset(f,-1,sizeof(f));
 dfs(0);
        dfs(0);
 printf("%d\n",dp[0][M+1]);
        printf("%d\n",dp[0][M+1]);
 }
    }
 return 0;
    return 0;
 }
}


posted @ 
2010-08-05 18:00 wuxu 阅读(1001) | 
评论 (4) | 
编辑 收藏