P1130 红牌
题目描述
某地临时居民想获得长期居住权就必须申请拿到红牌。获得红牌的过程是相当复杂 ,一共包括NN个步骤。每一步骤都由政府的某个工作人员负责检查你所提交的材料是否符合条件。为了加快进程,每一步政府都派了MM个工作人员来检查材料。不幸的是,并不是每一个工作人员效率都很高。尽管如此,为了体现“公开政府”的政策,政府部门把每一个工作人员的处理一个申请所花天数都对外界公开。
为了防止所有申请人都到效率高的工作人员去申请。这M \times NM×N个工作人员被分成MM个小组。每一组在每一步都有一个工作人员。申请人可以选择任意一个小组也可以更换小组。但是更换小组是很严格的,一定要相邻两个步骤之间来更换,而不能在某一步骤已经开始但还没结束的时候提出更换,并且也只能从原来的小组I更换到小组I+1I+1,当然从小组MM可以更换到小组11。对更换小组的次数没有限制。
例如:下面是33个小组,每个小组44个步骤工作天数:
小组11 : 2, 6 ,1 ,8
小组22 : 3,6, 2, 6
小组33 : 4, 2 ,3 ,6
例子中,可以选择小组11来完成整个过程一共花了2+6+1+8=17天,也可以从小组22开始第一步,然后第二步更换到小组3,第三步到小组11,第四步再到小组22,这样一共花了3+2+1+6=12天。你可以发现没有比这样效率更高的选择。
你的任务是求出完成申请所花最少天数。
输入格式
第一行是两个正整数N和M,表示步数和小组数。接下来有MM行,每行NN个非负整数,第i+1(1 \le i \le M)i+1(1≤i≤M)行的第j个数表示小组ii完成第j步所花的天数,天数都不超过1000000。
输出格式
一个正整数,为完成所有步所需最少天数。
输入输出样例
输入 #1
4 3 2 6 1 8 3 6 2 6 4 2 3 6
输出 #1
12
动态规划
#include<bits/stdc++.h> using namespace std; int n,m,a[2001][2001],b[2001][2001],c[2001],l=9999999; int main(){ cin>>n>>m; for(int j=1;j<=m;j++) { for(int i=1;i<=n;i++) { cin>>a[i][j]; } b[1][j]=a[1][j]; } for(int i=2;i<=n;i++) { for(int j=1;j<=m;j++) { if(j==1) b[i][j]=min(b[i-1][m],b[i-1][j])+a[i][j]; else b[i][j]=min(b[i-1][j-1],b[i-1][j])+a[i][j]; } } for(int i=1;i<=m;i++) { if(b[n][i]<l) l=b[n][i]; } cout<<l; }